code:
/* Copyright (c) 2017-2019, 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 BATCHING_ADAPTER_H
#define BATCHING_ADAPTER_H

#include <LocAdapterBase.h>
#include <LocContext.h>
#include <LocationAPI.h>
#include <map>

using namespace loc_core;

class BatchingAdapter : public LocAdapterBase {

    /* ==== BATCHING ======================================================================= */
    typedef struct {
        uint32_t accumulatedDistanceOngoingBatch;
        uint32_t accumulatedDistanceThisTrip;
        uint32_t accumulatedDistanceOnTripRestart;
        uint32_t tripDistance;
        uint32_t tripTBFInterval;
    } TripSessionStatus;
    typedef std::map<uint32_t, TripSessionStatus> TripSessionStatusMap;
    typedef std::map<LocationSessionKey, BatchingOptions> BatchingSessionMap;

    BatchingSessionMap mBatchingSessions;
    TripSessionStatusMap mTripSessions;
    uint32_t mOngoingTripDistance;
    uint32_t mOngoingTripTBFInterval;
    bool mTripWithOngoingTBFDropped;
    bool mTripWithOngoingTripDistanceDropped;

    void startTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
                                    const BatchingOptions& batchingOptions);
    void stopTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
                                   bool restartNeeded,
                                   const BatchingOptions& batchOptions);
    inline void stopTripBatchingMultiplex(LocationAPI* client, uint32_t id) {
        BatchingOptions batchOptions;
        stopTripBatchingMultiplex(client, id, false, batchOptions);
    };
    void stopTripBatchingMultiplexCommon(LocationError err,
                                         LocationAPI* client,
                                         uint32_t sessionId,
                                         bool restartNeeded,
                                         const BatchingOptions& batchOptions);
    void restartTripBatching(bool queryAccumulatedDistance, uint32_t accDist = 0,
                             uint32_t numbatchedPos = 0);
    void printTripReport();

    /* ==== CONFIGURATION ================================================================== */
    uint32_t mBatchingTimeout;
    uint32_t mBatchingAccuracy;
    size_t mBatchSize;
    size_t mTripBatchSize;

protected:

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

public:
    BatchingAdapter();
    virtual ~BatchingAdapter() {}

    /* ==== SSR ============================================================================ */
    /* ======== EVENTS ====(Called from QMI Thread)========================================= */
    virtual void handleEngineUpEvent();
    /* ======== UTILITIES ================================================================== */
    void restartSessions();

    /* ==== BATCHING ======================================================================= */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    uint32_t startBatchingCommand(LocationAPI* client, BatchingOptions &batchOptions);
    void updateBatchingOptionsCommand(
            LocationAPI* client, uint32_t id, BatchingOptions& batchOptions);
    void stopBatchingCommand(LocationAPI* client, uint32_t id);
    void getBatchedLocationsCommand(LocationAPI* client, uint32_t id, size_t count);
    /* ======== RESPONSES ================================================================== */
    void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
    /* ======== UTILITIES ================================================================== */
    bool hasBatchingCallback(LocationAPI* client);
    bool isBatchingSession(LocationAPI* client, uint32_t sessionId);
    bool isTripSession(uint32_t sessionId);
    void saveBatchingSession(LocationAPI* client, uint32_t sessionId,
                             const BatchingOptions& batchingOptions);
    void eraseBatchingSession(LocationAPI* client, uint32_t sessionId);
    uint32_t autoReportBatchingSessionsCount();
    void startBatching(LocationAPI* client, uint32_t sessionId,
                       const BatchingOptions& batchingOptions);
    void stopBatching(LocationAPI* client, uint32_t sessionId, bool restartNeeded,
                      const BatchingOptions& batchOptions);
    void stopBatching(LocationAPI* client, uint32_t sessionId) {
        BatchingOptions batchOptions;
        stopBatching(client, sessionId, false, batchOptions);
    };

    /* ==== REPORTS ======================================================================== */
    /* ======== EVENTS ====(Called from QMI Thread)========================================= */
    void reportLocationsEvent(const Location* locations, size_t count,
            BatchingMode batchingMode);
    void reportCompletedTripsEvent(uint32_t accumulatedDistance);
    void reportBatchStatusChangeEvent(BatchingStatus batchStatus);
    /* ======== UTILITIES ================================================================== */
    void reportLocations(Location* locations, size_t count, BatchingMode batchingMode);
    void reportBatchStatusChange(BatchingStatus batchStatus,
            std::list<uint32_t> & completedTripsList);

    /* ==== CONFIGURATION ================================================================== */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    void readConfigCommand();
    void setConfigCommand();
    /* ======== UTILITIES ================================================================== */
    void setBatchSize(size_t batchSize) { mBatchSize = batchSize; }
    size_t getBatchSize() { return mBatchSize; }
    void setTripBatchSize(size_t batchSize) { mTripBatchSize = batchSize; }
    size_t getTripBatchSize() { return mTripBatchSize; }
    void setBatchingTimeout(uint32_t batchingTimeout) { mBatchingTimeout = batchingTimeout; }
    uint32_t getBatchingTimeout() { return mBatchingTimeout; }
    void setBatchingAccuracy(uint32_t accuracy) { mBatchingAccuracy = accuracy; }
    uint32_t getBatchingAccuracy() { return mBatchingAccuracy; }

};

#endif /* BATCHING_ADAPTER_H */


code:
/* Copyright (c) 2017-2019, 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 "BatchingAdapter.h"
#include "location_interface.h"

static BatchingAdapter* gBatchingAdapter = 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 startBatching(LocationAPI* client, BatchingOptions&);
static void stopBatching(LocationAPI* client, uint32_t id);
static void updateBatchingOptions(LocationAPI* client, uint32_t id, BatchingOptions&);
static void getBatchedLocations(LocationAPI* client, uint32_t id, size_t count);

static const BatchingInterface gBatchingInterface = {
    sizeof(BatchingInterface),
    initialize,
    deinitialize,
    addClient,
    removeClient,
    requestCapabilities,
    startBatching,
    stopBatching,
    updateBatchingOptions,
    getBatchedLocations
};

#ifndef DEBUG_X86
extern "C" const BatchingInterface* getBatchingInterface()
#else
const BatchingInterface* getBatchingInterface()
#endif // DEBUG_X86
{
   return &gBatchingInterface;
}

static void initialize()
{
    if (NULL == gBatchingAdapter) {
        gBatchingAdapter = new BatchingAdapter();
    }
}

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

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

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

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

static uint32_t startBatching(LocationAPI* client, BatchingOptions &batchOptions)
{
    if (NULL != gBatchingAdapter) {
        return gBatchingAdapter->startBatchingCommand(client, batchOptions);
    } else {
        return 0;
    }
}

static void stopBatching(LocationAPI* client, uint32_t id)
{
    if (NULL != gBatchingAdapter) {
        gBatchingAdapter->stopBatchingCommand(client, id);
    }
}

static void updateBatchingOptions(
        LocationAPI* client, uint32_t id, BatchingOptions& batchOptions)
{
    if (NULL != gBatchingAdapter) {
        gBatchingAdapter->updateBatchingOptionsCommand(client, id, batchOptions);
    }
}

static void getBatchedLocations(LocationAPI* client, uint32_t id, size_t count)
{
    if (NULL != gBatchingAdapter) {
        gBatchingAdapter->getBatchedLocationsCommand(client, id, count);
    }
}

license: unknown


code:
cc_library_shared {

    name: "libloc_core",
    vendor: true,

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

    srcs: [
        "LocApiBase.cpp",
        "LocAdapterBase.cpp",
        "ContextBase.cpp",
        "LocContext.cpp",
        "loc_core_log.cpp",
        "data-items/DataItemsFactoryProxy.cpp",
        "SystemStatusOsObserver.cpp",
        "SystemStatus.cpp",
    ],

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

    local_include_dirs: [
        "data-items",
        "observer",
    ],

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

}

cc_library_headers {

    name: "libloc_core_headers",
    vendor: true,
    export_include_dirs: ["."] + [
        "data-items",
        "observer",
    ],
}


code:
/* Copyright (c) 2011-2014,2016-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_NDEBUG 0
#define LOG_TAG "LocSvc_CtxBase"

#include <dlfcn.h>
#include <unistd.h>
#include <ContextBase.h>
#include <msg_q.h>
#include <loc_target.h>
#include <loc_pla.h>
#include <loc_log.h>

namespace loc_core {

#define SLL_LOC_API_LIB_NAME "libsynergy_loc_api.so"
#define LOC_APIV2_0_LIB_NAME "libloc_api_v02.so"
#define IS_SS5_HW_ENABLED  1

loc_gps_cfg_s_type ContextBase::mGps_conf {};
loc_sap_cfg_s_type ContextBase::mSap_conf {};
bool ContextBase::sIsEngineCapabilitiesKnown = false;
uint64_t ContextBase::sSupportedMsgMask = 0;
bool ContextBase::sGnssMeasurementSupported = false;
uint8_t ContextBase::sFeaturesSupported[MAX_FEATURE_LENGTH];
GnssNMEARptRate ContextBase::sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ;
LocationCapabilitiesMask ContextBase::sQwesFeatureMask = 0;

const loc_param_s_type ContextBase::mGps_conf_table[] =
{
  {"GPS_LOCK",                       &mGps_conf.GPS_LOCK,                       NULL, 'n'},
  {"SUPL_VER",                       &mGps_conf.SUPL_VER,                       NULL, 'n'},
  {"LPP_PROFILE",                    &mGps_conf.LPP_PROFILE,                    NULL, 'n'},
  {"A_GLONASS_POS_PROTOCOL_SELECT",  &mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT,  NULL, 'n'},
  {"LPPE_CP_TECHNOLOGY",             &mGps_conf.LPPE_CP_TECHNOLOGY,             NULL, 'n'},
  {"LPPE_UP_TECHNOLOGY",             &mGps_conf.LPPE_UP_TECHNOLOGY,             NULL, 'n'},
  {"AGPS_CERT_WRITABLE_MASK",        &mGps_conf.AGPS_CERT_WRITABLE_MASK,        NULL, 'n'},
  {"SUPL_MODE",                      &mGps_conf.SUPL_MODE,                      NULL, 'n'},
  {"SUPL_ES",                        &mGps_conf.SUPL_ES,                        NULL, 'n'},
  {"INTERMEDIATE_POS",               &mGps_conf.INTERMEDIATE_POS,               NULL, 'n'},
  {"ACCURACY_THRES",                 &mGps_conf.ACCURACY_THRES,                 NULL, 'n'},
  {"NMEA_PROVIDER",                  &mGps_conf.NMEA_PROVIDER,                  NULL, 'n'},
  {"NMEA_REPORT_RATE",               &mGps_conf.NMEA_REPORT_RATE,               NULL, 's'},
  {"CAPABILITIES",                   &mGps_conf.CAPABILITIES,                   NULL, 'n'},
  {"XTRA_SERVER_1",                  &mGps_conf.XTRA_SERVER_1,                  NULL, 's'},
  {"XTRA_SERVER_2",                  &mGps_conf.XTRA_SERVER_2,                  NULL, 's'},
  {"XTRA_SERVER_3",                  &mGps_conf.XTRA_SERVER_3,                  NULL, 's'},
  {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",
           &mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL,          NULL, 'n'},
  {"AGPS_CONFIG_INJECT",             &mGps_conf.AGPS_CONFIG_INJECT,             NULL, 'n'},
  {"EXTERNAL_DR_ENABLED",            &mGps_conf.EXTERNAL_DR_ENABLED,                  NULL, 'n'},
  {"SUPL_HOST",                      &mGps_conf.SUPL_HOST,                      NULL, 's'},
  {"SUPL_PORT",                      &mGps_conf.SUPL_PORT,                      NULL, 'n'},
  {"MODEM_TYPE",                     &mGps_conf.MODEM_TYPE,                     NULL, 'n' },
  {"MO_SUPL_HOST",                   &mGps_conf.MO_SUPL_HOST,                   NULL, 's' },
  {"MO_SUPL_PORT",                   &mGps_conf.MO_SUPL_PORT,                   NULL, 'n' },
  {"CONSTRAINED_TIME_UNCERTAINTY_ENABLED",
           &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED,      NULL, 'n'},
  {"CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD",
           &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD,    NULL, 'f'},
  {"CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET",
           &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET, NULL, 'n'},
  {"POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED",
           &mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED, NULL, 'n'},
  {"PROXY_APP_PACKAGE_NAME",         &mGps_conf.PROXY_APP_PACKAGE_NAME,         NULL, 's' },
  {"CP_MTLR_ES",                     &mGps_conf.CP_MTLR_ES,                     NULL, 'n' },
  {"GNSS_DEPLOYMENT",  &mGps_conf.GNSS_DEPLOYMENT, NULL, 'n'},
  {"CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED",
           &mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED, NULL, 'n'},
  {"NMEA_TAG_BLOCK_GROUPING_ENABLED", &mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED, NULL, 'n'},
  {"NI_SUPL_DENY_ON_NFW_LOCKED",  &mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED, NULL, 'n'},
  {"ENABLE_NMEA_PRINT",  &mGps_conf.ENABLE_NMEA_PRINT, NULL, 'n'}
};

const loc_param_s_type ContextBase::mSap_conf_table[] =
{
  {"GYRO_BIAS_RANDOM_WALK",          &mSap_conf.GYRO_BIAS_RANDOM_WALK,          &mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
  {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY",     &mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,    &mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY",     &mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,    &mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"RATE_RANDOM_WALK_SPECTRAL_DENSITY",      &mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,     &mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY",  &mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"SENSOR_ACCEL_BATCHES_PER_SEC",   &mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,   NULL, 'n'},
  {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'},
  {"SENSOR_GYRO_BATCHES_PER_SEC",    &mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC,    NULL, 'n'},
  {"SENSOR_GYRO_SAMPLES_PER_BATCH",  &mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,  NULL, 'n'},
  {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH",   &mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,   NULL, 'n'},
  {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
  {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH",    &mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,    NULL, 'n'},
  {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH",  &mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,  NULL, 'n'},
  {"SENSOR_CONTROL_MODE",            &mSap_conf.SENSOR_CONTROL_MODE,            NULL, 'n'},
  {"SENSOR_ALGORITHM_CONFIG_MASK",   &mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK,   NULL, 'n'}
};

void ContextBase::readConfig()
{
    static bool confReadDone = false;
    if (!confReadDone) {
        confReadDone = true;
        /*Defaults for gps.conf*/
        mGps_conf.INTERMEDIATE_POS = 0;
        mGps_conf.ACCURACY_THRES = 0;
        mGps_conf.NMEA_PROVIDER = 0;
        mGps_conf.GPS_LOCK = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
        mGps_conf.SUPL_VER = 0x10000;
        mGps_conf.SUPL_MODE = 0x1;
        mGps_conf.SUPL_ES = 0;
        mGps_conf.CP_MTLR_ES = 0;
        mGps_conf.SUPL_HOST[0] = 0;
        mGps_conf.SUPL_PORT = 0;
        mGps_conf.CAPABILITIES = 0x7;
        /* LTE Positioning Profile configuration is disable by default*/
        mGps_conf.LPP_PROFILE = 0;
        /*By default no positioning protocol is selected on A-GLONASS system*/
        mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
        /*Use emergency PDN by default*/
        mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1;
        /* By default no LPPe CP technology is enabled*/
        mGps_conf.LPPE_CP_TECHNOLOGY = 0;
        /* By default no LPPe UP technology is enabled*/
        mGps_conf.LPPE_UP_TECHNOLOGY = 0;
        /* By default we use unknown modem type*/
        mGps_conf.MODEM_TYPE = 2;

        /*Defaults for sap.conf*/
        mSap_conf.GYRO_BIAS_RANDOM_WALK = 0;
        mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
        mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
        mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
        mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
        mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
        mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
        mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
        mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
        mSap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
        mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/
        /* Values MUST be set by OEMs in configuration for sensor-assisted
          navigation to work. There are NO default values */
        mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
        mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
        mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
        mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
        mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
        mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
        mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
        mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
        mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;

        /* None of the 10 slots for agps certificates are writable by default */
        mGps_conf.AGPS_CERT_WRITABLE_MASK = 0;

        /* inject supl config to modem with config values from config.xml or gps.conf, default 1 */
        mGps_conf.AGPS_CONFIG_INJECT = 1;

        /* default configuration value of constrained time uncertainty mode:
           feature disabled, time uncertainty threshold defined by modem,
           and unlimited power budget */
#ifdef FEATURE_AUTOMOTIVE
        mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED = 1;
#else
        mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED = 0;
#endif
        mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD = 0.0;
        mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET = 0;

        /* default configuration value of position assisted clock estimator mode */
        mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED = 0;
        /* default configuration QTI GNSS H/W */
        mGps_conf.GNSS_DEPLOYMENT = 0;
        mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0;
        /* default NMEA Tag Block Grouping is disabled */
        mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED = 0;
        /* default configuration for NI_SUPL_DENY_ON_NFW_LOCKED */
        mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED = 1;
        /* By default NMEA Printing is disabled */
        mGps_conf.ENABLE_NMEA_PRINT = 0;

        UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table);
        UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table);

        if (strncmp(mGps_conf.NMEA_REPORT_RATE, "1HZ", sizeof(mGps_conf.NMEA_REPORT_RATE)) == 0) {
            /* NMEA reporting is configured at 1Hz*/
            sNmeaReportRate = GNSS_NMEA_REPORT_RATE_1HZ;
        } else {
            sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ;
        }
        LOC_LOGI("%s] GNSS Deployment: %s", __FUNCTION__,
                ((mGps_conf.GNSS_DEPLOYMENT == 1) ? "SS5" :
                ((mGps_conf.GNSS_DEPLOYMENT == 2) ? "QFUSION" : "QGNSS")));

        switch (getTargetGnssType(loc_get_target())) {
          case GNSS_GSS:
          case GNSS_AUTO:
             // For APQ targets, MSA/MSB capabilities should be reset
             mGps_conf.CAPABILITIES &= ~(LOC_GPS_CAPABILITY_MSA | LOC_GPS_CAPABILITY_MSB);
             break;
          default:
             break;
        }
    }
}

uint32_t ContextBase::getCarrierCapabilities() {
    #define carrierMSA (uint32_t)0x2
    #define carrierMSB (uint32_t)0x1
    #define gpsConfMSA (uint32_t)0x4
    #define gpsConfMSB (uint32_t)0x2
    uint32_t capabilities = mGps_conf.CAPABILITIES;
    if ((mGps_conf.SUPL_MODE & carrierMSA) != carrierMSA) {
        capabilities &= ~gpsConfMSA;
    }
    if ((mGps_conf.SUPL_MODE & carrierMSB) != carrierMSB) {
        capabilities &= ~gpsConfMSB;
    }

    LOC_LOGV("getCarrierCapabilities: CAPABILITIES %x, SUPL_MODE %x, carrier capabilities %x",
             mGps_conf.CAPABILITIES, mGps_conf.SUPL_MODE, capabilities);
    return capabilities;
}

LBSProxyBase* ContextBase::getLBSProxy(const char* libName)
{
    LBSProxyBase* proxy = NULL;
    LOC_LOGD("%s:%d]: getLBSProxy libname: %s\n", __func__, __LINE__, libName);
    void* lib = dlopen(libName, RTLD_NOW);

    if ((void*)NULL != lib) {
        getLBSProxy_t* getter = (getLBSProxy_t*)dlsym(lib, "getLBSProxy");
        if (NULL != getter) {
            proxy = (*getter)();
        }
    }
    else
    {
        LOC_LOGW("%s:%d]: FAILED TO LOAD libname: %s\n", __func__, __LINE__, libName);
    }
    if (NULL == proxy) {
        proxy = new LBSProxyBase();
    }
    LOC_LOGD("%s:%d]: Exiting\n", __func__, __LINE__);
    return proxy;
}

LocApiBase* ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask)
{
    LocApiBase* locApi = NULL;
    const char* libname = LOC_APIV2_0_LIB_NAME;

    // Check the target
    if (TARGET_NO_GNSS != loc_get_target()){

        if (NULL == (locApi = mLBSProxy->getLocApi(exMask, this))) {
            void *handle = NULL;

            if (IS_SS5_HW_ENABLED == mGps_conf.GNSS_DEPLOYMENT) {
                libname = SLL_LOC_API_LIB_NAME;
            }

            if ((handle = dlopen(libname, RTLD_NOW)) != NULL) {
                LOC_LOGD("%s:%d]: %s is present", __func__, __LINE__, libname);
                getLocApi_t* getter = (getLocApi_t*) dlsym(handle, "getLocApi");
                if (getter != NULL) {
                    LOC_LOGD("%s:%d]: getter is not NULL of %s", __func__,
                            __LINE__, libname);
                    locApi = (*getter)(exMask, this);
                }
            }
            // only RPC is the option now
            else {
                LOC_LOGD("%s:%d]: libloc_api_v02.so is NOT present. Trying RPC",
                        __func__, __LINE__);
                handle = dlopen("libloc_api-rpc-qc.so", RTLD_NOW);
                if (NULL != handle) {
                    getLocApi_t* getter = (getLocApi_t*) dlsym(handle, "getLocApi");
                    if (NULL != getter) {
                        LOC_LOGD("%s:%d]: getter is not NULL in RPC", __func__,
                                __LINE__);
                        locApi = (*getter)(exMask, this);
                    }
                }
            }
        }
    }

    // locApi could still be NULL at this time
    // we would then create a dummy one
    if (NULL == locApi) {
        locApi = new LocApiBase(exMask, this);
    }

    return locApi;
}

ContextBase::ContextBase(const MsgTask* msgTask,
                         LOC_API_ADAPTER_EVENT_MASK_T exMask,
                         const char* libName) :
    mLBSProxy(getLBSProxy(libName)),
    mMsgTask(msgTask),
    mLocApi(createLocApi(exMask)),
    mLocApiProxy(mLocApi->getLocApiProxy())
{
}

void ContextBase::setEngineCapabilities(uint64_t supportedMsgMask,
       uint8_t *featureList, bool gnssMeasurementSupported) {

    if (ContextBase::sIsEngineCapabilitiesKnown == false) {
        ContextBase::sSupportedMsgMask = supportedMsgMask;
        ContextBase::sGnssMeasurementSupported = gnssMeasurementSupported;
        if (featureList != NULL) {
            memcpy((void *)ContextBase::sFeaturesSupported,
                    (void *)featureList, sizeof(ContextBase::sFeaturesSupported));
        }

        /* */
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
            static uint8_t isSapModeKnown = 0;

            if (!isSapModeKnown) {
                /* Check if SAP is PREMIUM_ENV_AIDING in izat.conf */
                char conf_feature_sap[LOC_MAX_PARAM_STRING];
                loc_param_s_type izat_conf_feature_table[] =
                {
                    { "SAP",           &conf_feature_sap,           &isSapModeKnown, 's' }
                };
                UTIL_READ_CONF(LOC_PATH_IZAT_CONF, izat_conf_feature_table);

                /* Disable this feature if SAP is not PREMIUM_ENV_AIDING in izat.conf */
                if (strcmp(conf_feature_sap, "PREMIUM_ENV_AIDING") != 0) {
                    uint8_t arrayIndex = LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION >> 3;
                    uint8_t bitPos = LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION & 7;

                    if (arrayIndex < MAX_FEATURE_LENGTH) {
                        /* To disable the feature we need to reset the bit on the "bitPos"
                           position, so shift a "1" to the left by "bitPos" */
                        ContextBase::sFeaturesSupported[arrayIndex] &= ~(1 << bitPos);
                    }
                }
            }
        }
        ContextBase::sIsEngineCapabilitiesKnown = true;
    }
}

bool ContextBase::isFeatureSupported(uint8_t featureVal)
{
    uint8_t arrayIndex = featureVal >> 3;
    uint8_t bitPos = featureVal & 7;

    if (arrayIndex >= MAX_FEATURE_LENGTH) return false;
    return ((ContextBase::sFeaturesSupported[arrayIndex] >> bitPos ) & 0x1);
}

bool ContextBase::gnssConstellationConfig() {
    return sGnssMeasurementSupported;
}

}


code:
/* Copyright (c) 2011-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 __LOC_CONTEXT_BASE__
#define __LOC_CONTEXT_BASE__

#include <stdbool.h>
#include <ctype.h>
#include <MsgTask.h>
#include <LocApiBase.h>
#include <LBSProxyBase.h>
#include <loc_cfg.h>
#ifdef NO_UNORDERED_SET_OR_MAP
    #include <map>
#else
    #include <unordered_map>
#endif

/* GPS.conf support */
/* NOTE: the implementaiton of the parser casts number
   fields to 32 bit. To ensure all 'n' fields working,
   they must all be 32 bit fields. */
typedef struct loc_gps_cfg_s
{
    uint32_t       INTERMEDIATE_POS;
    uint32_t       ACCURACY_THRES;
    uint32_t       SUPL_VER;
    uint32_t       SUPL_MODE;
    uint32_t       SUPL_ES;
    uint32_t       CAPABILITIES;
    uint32_t       LPP_PROFILE;
    char           XTRA_SERVER_1[LOC_MAX_PARAM_STRING];
    char           XTRA_SERVER_2[LOC_MAX_PARAM_STRING];
    char           XTRA_SERVER_3[LOC_MAX_PARAM_STRING];
    uint32_t       USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL;
    uint32_t       NMEA_PROVIDER;
    char           NMEA_REPORT_RATE[LOC_MAX_PARAM_NAME];
    GnssConfigGpsLock   GPS_LOCK;
    uint32_t       A_GLONASS_POS_PROTOCOL_SELECT;
    uint32_t       AGPS_CERT_WRITABLE_MASK;
    uint32_t       AGPS_CONFIG_INJECT;
    uint32_t       LPPE_CP_TECHNOLOGY;
    uint32_t       LPPE_UP_TECHNOLOGY;
    uint32_t       EXTERNAL_DR_ENABLED;
    char           SUPL_HOST[LOC_MAX_PARAM_STRING];
    uint32_t       SUPL_PORT;
    uint32_t       MODEM_TYPE;
    char           MO_SUPL_HOST[LOC_MAX_PARAM_STRING];
    uint32_t       MO_SUPL_PORT;
    uint32_t       CONSTRAINED_TIME_UNCERTAINTY_ENABLED;
    double         CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD;
    uint32_t       CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET;
    uint32_t       POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED;
    char           PROXY_APP_PACKAGE_NAME[LOC_MAX_PARAM_STRING];
    uint32_t       CP_MTLR_ES;
    uint32_t       GNSS_DEPLOYMENT;
    uint32_t       CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED;
    uint32_t       NI_SUPL_DENY_ON_NFW_LOCKED;
    uint32_t       ENABLE_NMEA_PRINT;
    uint32_t       NMEA_TAG_BLOCK_GROUPING_ENABLED;
} loc_gps_cfg_s_type;

/* NOTE: the implementation of the parser casts number
   fields to 32 bit. To ensure all 'n' fields working,
   they must all be 32 bit fields. */
/* Meanwhile, *_valid fields are 8 bit fields, and 'f'
   fields are double. Rigid as they are, it is the
   the status quo, until the parsing mechanism is
   changed, that is. */
typedef struct
{
    uint8_t        GYRO_BIAS_RANDOM_WALK_VALID;
    double         GYRO_BIAS_RANDOM_WALK;
    uint32_t       SENSOR_ACCEL_BATCHES_PER_SEC;
    uint32_t       SENSOR_ACCEL_SAMPLES_PER_BATCH;
    uint32_t       SENSOR_GYRO_BATCHES_PER_SEC;
    uint32_t       SENSOR_GYRO_SAMPLES_PER_BATCH;
    uint32_t       SENSOR_ACCEL_BATCHES_PER_SEC_HIGH;
    uint32_t       SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH;
    uint32_t       SENSOR_GYRO_BATCHES_PER_SEC_HIGH;
    uint32_t       SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH;
    uint32_t       SENSOR_CONTROL_MODE;
    uint32_t       SENSOR_ALGORITHM_CONFIG_MASK;
    uint8_t        ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
    double         ACCEL_RANDOM_WALK_SPECTRAL_DENSITY;
    uint8_t        ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
    double         ANGLE_RANDOM_WALK_SPECTRAL_DENSITY;
    uint8_t        RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
    double         RATE_RANDOM_WALK_SPECTRAL_DENSITY;
    uint8_t        VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
    double         VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY;
} loc_sap_cfg_s_type;

using namespace loc_util;

namespace loc_core {

class LocAdapterBase;

class ContextBase {
    static LBSProxyBase* getLBSProxy(const char* libName);
    LocApiBase* createLocApi(LOC_API_ADAPTER_EVENT_MASK_T excludedMask);
    static const loc_param_s_type mGps_conf_table[];
    static const loc_param_s_type mSap_conf_table[];
protected:
    const LBSProxyBase* mLBSProxy;
    const MsgTask* mMsgTask;
    LocApiBase* mLocApi;
    LocApiProxyBase *mLocApiProxy;

public:
    ContextBase(const MsgTask* msgTask,
                LOC_API_ADAPTER_EVENT_MASK_T exMask,
                const char* libName);
    inline virtual ~ContextBase() {
        if (nullptr != mLocApi) {
            mLocApi->destroy();
            mLocApi = nullptr;
        }
        if (nullptr != mLBSProxy) {
            delete mLBSProxy;
            mLBSProxy = nullptr;
        }
    }

    inline const MsgTask* getMsgTask() { return mMsgTask; }
    inline LocApiBase* getLocApi() { return mLocApi; }
    inline LocApiProxyBase* getLocApiProxy() { return mLocApiProxy; }
    inline bool hasAgpsExtendedCapabilities() { return mLBSProxy->hasAgpsExtendedCapabilities(); }
    inline bool hasNativeXtraClient() { return mLBSProxy->hasNativeXtraClient(); }
    inline void modemPowerVote(bool power) const { return mLBSProxy->modemPowerVote(power); }
    inline IzatDevId_t getIzatDevId() const {
        return mLBSProxy->getIzatDevId();
    }
    inline void sendMsg(const LocMsg *msg) { getMsgTask()->sendMsg(msg); }

    static loc_gps_cfg_s_type mGps_conf;
    static loc_sap_cfg_s_type mSap_conf;
    static bool sIsEngineCapabilitiesKnown;
    static uint64_t sSupportedMsgMask;
    static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH];
    static bool sGnssMeasurementSupported;
    static GnssNMEARptRate sNmeaReportRate;
    static LocationCapabilitiesMask sQwesFeatureMask;

    void readConfig();
    static uint32_t getCarrierCapabilities();
    void setEngineCapabilities(uint64_t supportedMsgMask,
            uint8_t *featureList, bool gnssMeasurementSupported);

    static inline bool isEngineCapabilitiesKnown() {
        return sIsEngineCapabilitiesKnown;
    }

    static inline bool isMessageSupported(LocCheckingMessagesID msgID) {

        // confirm if msgID is not larger than the number of bits in
        // mSupportedMsg
        if ((uint64_t)msgID > (sizeof(sSupportedMsgMask) << 3)) {
            return false;
        } else {
            uint32_t messageChecker = 1 << msgID;
            return (messageChecker & sSupportedMsgMask) == messageChecker;
        }
    }

    /*
        Check if a feature is supported
    */
    static bool isFeatureSupported(uint8_t featureVal);

    /*
        Check if gnss measurement is supported
    */
    static bool gnssConstellationConfig();

    /*
        set QWES feature status info
    */
    static inline void setQwesFeatureStatus(
            const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) {
       std::unordered_map<LocationQwesFeatureType, bool>::const_iterator itr;
       static LocationQwesFeatureType locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_MAX];
       for (itr = featureMap.begin(); itr != featureMap.end(); ++itr) {
           LOC_LOGi("Feature : %d isValid: %d", itr->first, itr->second);
           locQwesFeatType[itr->first] = itr->second;
           switch (itr->first) {
               case LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_SV_EPH:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_PPE:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_PPE;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_PPE;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_QDR2:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR2;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR2;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_QDR3:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR3;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR3;
                   }
               break;
               case LOCATION_QWES_FEATURE_TYPE_VPE:
                   if (itr->second) {
                       sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_VPE;
                   } else {
                       sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_VPE;
                   }
               break;
           }
       }

       // Set CV2X basic when time freq and tunc is set
       // CV2X_BASIC  = LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY &
       //       LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY

       // Set CV2X premium when time freq and tunc is set
       // CV2X_PREMIUM = CV2X_BASIC & LOCATION_QWES_FEATURE_TYPE_QDR3 &
       //       LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE

       bool cv2xBasicEnabled = (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY]) &&
            (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY]);
       bool cv2xPremiumEnabled = cv2xBasicEnabled &&
            (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_QDR3]) &&
            (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE]);

       LOC_LOGd("CV2X_BASIC:%d, CV2X_PREMIUM:%d", cv2xBasicEnabled, cv2xPremiumEnabled);
       if (cv2xBasicEnabled) {
            sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC;
       } else {
            sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC;
       }
       if (cv2xPremiumEnabled) {
            sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM;
       } else {
            sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM;
       }
    }

    /*
        get QWES feature status info
    */
    static inline LocationCapabilitiesMask getQwesFeatureStatus() {
        return (ContextBase::sQwesFeatureMask);
    }

};

struct LocApiResponse: LocMsg {
    private:
        ContextBase& mContext;
        std::function<void (LocationError err)> mProcImpl;
        inline virtual void proc() const {
            mProcImpl(mLocationError);
        }
    protected:
        LocationError mLocationError;
    public:
        inline LocApiResponse(ContextBase& context,
                              std::function<void (LocationError err)> procImpl ) :
                              mContext(context), mProcImpl(procImpl) {}

        void returnToSender(const LocationError err) {
            mLocationError = err;
            mContext.sendMsg(this);
        }
};

struct LocApiCollectiveResponse: LocMsg {
    private:
        ContextBase& mContext;
        std::function<void (std::vector<LocationError> errs)> mProcImpl;
        inline virtual void proc() const {
            mProcImpl(mLocationErrors);
        }
    protected:
        std::vector<LocationError> mLocationErrors;
    public:
        inline LocApiCollectiveResponse(ContextBase& context,
                              std::function<void (std::vector<LocationError> errs)> procImpl ) :
                              mContext(context), mProcImpl(procImpl) {}
        inline virtual ~LocApiCollectiveResponse() {
        }

        void returnToSender(std::vector<LocationError>& errs) {
            mLocationErrors = errs;
            mContext.sendMsg(this);
        }
};

template <typename DATA>
struct LocApiResponseData: LocMsg {
    private:
        ContextBase& mContext;
        std::function<void (LocationError err, DATA data)> mProcImpl;
        inline virtual void proc() const {
            mProcImpl(mLocationError, mData);
        }
    protected:
        LocationError mLocationError;
        DATA mData;
    public:
        inline LocApiResponseData(ContextBase& context,
                              std::function<void (LocationError err, DATA data)> procImpl ) :
                              mContext(context), mProcImpl(procImpl) {}

        void returnToSender(const LocationError err, const DATA data) {
            mLocationError = err;
            mData = data;
            mContext.sendMsg(this);
        }
};

} // namespace loc_core

#endif //__LOC_CONTEXT_BASE__


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 ENGINE_HUB_PROXY_BASE_H
#define ENGINE_HUB_PROXY_BASE_H
#ifdef NO_UNORDERED_SET_OR_MAP
    #include <map>
#else
    #include <unordered_map>
#endif

namespace loc_core {

using namespace loc_util;

class EngineHubProxyBase {
public:
    inline EngineHubProxyBase() {
    }
    inline virtual ~EngineHubProxyBase() {}

    // gnss session related functions
    inline virtual bool gnssStartFix() {
        return false;
    }

    inline virtual bool gnssStopFix() {
        return false;
    }

    inline virtual bool gnssSetFixMode(const LocPosMode &params) {
        (void) params;
        return false;
    }

    inline virtual bool gnssDeleteAidingData(const GnssAidingData &aidingData) {
        (void) aidingData;
        return false;
    }

    // GNSS reports
    inline virtual bool gnssReportPosition(const UlpLocation &location,
                                           const GpsLocationExtended &locationExtended,
                                           enum loc_sess_status status) {
        (void) location;
        (void) locationExtended;
        (void) status;
        return false;
    }

    inline virtual bool gnssReportSv(const GnssSvNotification& svNotify) {
        (void) svNotify;
        return false;
    }

    inline virtual bool gnssReportSvMeasurement(const GnssSvMeasurementSet& svMeasurementSet) {
        (void) svMeasurementSet;
        return false;
    }

    inline virtual bool gnssReportSvPolynomial(const GnssSvPolynomial& svPolynomial) {
        (void) svPolynomial;
        return false;
    }

    inline virtual bool gnssReportSvEphemeris(const GnssSvEphemerisReport& svEphemeris) {
        (void) svEphemeris;
        return false;
    }

    inline virtual bool gnssReportSystemInfo(const LocationSystemInfo& systemInfo) {
        (void) systemInfo;
        return false;
    }

    inline virtual bool gnssReportKlobucharIonoModel(const GnssKlobucharIonoModel& ionoModel) {
        (void) ionoModel;
        return false;
    }

    inline virtual bool gnssReportAdditionalSystemInfo(
            const GnssAdditionalSystemInfo& additionalSystemInfo) {
        (void) additionalSystemInfo;
        return false;
    }

    inline virtual bool configLeverArm(const LeverArmConfigInfo& configInfo) {
        (void) configInfo;
        return false;
    }

    inline virtual bool configDeadReckoningEngineParams(
            const DeadReckoningEngineConfig& dreConfig) {
        (void) dreConfig;
        return false;
    }

    inline virtual bool configEngineRunState(
            PositioningEngineMask engType, LocEngineRunState engState) {
        (void) engType;
        (void) engState;
        return false;
    }
};

typedef std::function<void(int count, EngineLocationInfo* locationArr)>
        GnssAdapterReportEnginePositionsEventCb;

typedef std::function<void(const GnssSvNotification& svNotify,
                           bool fromEngineHub)>
        GnssAdapterReportSvEventCb;

typedef std::function<void(const GnssAidingDataSvMask& svDataMask)>
        GnssAdapterReqAidingDataCb;

typedef std::function<void(bool nHzNeeded, bool nHzMeasNeeded)>
        GnssAdapterUpdateNHzRequirementCb;

typedef std::function<void(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)>
        GnssAdapterUpdateQwesFeatureStatusCb;

// potential parameters: message queue: MsgTask * msgTask;
// callback function to report back dr and ppe position and sv report
typedef EngineHubProxyBase* (getEngHubProxyFn)(
        const MsgTask * msgTask,
        IOsObserver* osObserver,
        GnssAdapterReportEnginePositionsEventCb positionEventCb,
        GnssAdapterReportSvEventCb svEventCb,
        GnssAdapterReqAidingDataCb reqAidingDataCb,
        GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb,
        GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb);

} // namespace loc_core

#endif // ENGINE_HUB_PROXY_BASE_H


code:
/* Copyright (c) 2013-2015, 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 IZAT_PROXY_BASE_H
#define IZAT_PROXY_BASE_H
#include <gps_extended.h>

namespace loc_core {

class LocApiBase;
class LocAdapterBase;
class ContextBase;

class LBSProxyBase {
    friend class ContextBase;
    inline virtual LocApiBase*
        getLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask,
                  ContextBase* context) const {

        (void)exMask;
        (void)context;
        return NULL;
    }
protected:
    inline LBSProxyBase() {}
public:
    inline virtual ~LBSProxyBase() {}
    inline virtual bool hasAgpsExtendedCapabilities() const { return false; }
    inline virtual void modemPowerVote(bool power) const {

        (void)power;
    }
    virtual void injectFeatureConfig(ContextBase* context) const {

        (void)context;
    }
    inline virtual bool hasNativeXtraClient() const { return false; }
    inline virtual IzatDevId_t getIzatDevId() const { return 0; }
};

typedef LBSProxyBase* (getLBSProxy_t)();

} // namespace loc_core

#endif // IZAT_PROXY_BASE_H


code:
/* Copyright (c) 2011-2014, 2016-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_NDEBUG 0
#define LOG_TAG "LocSvc_LocAdapterBase"

#include <dlfcn.h>
#include <LocAdapterBase.h>
#include <loc_target.h>
#include <log_util.h>
#include <LocAdapterProxyBase.h>

namespace loc_core {

// This is the top level class, so the constructor will
// always gets called. Here we prepare for the default.
// But if getLocApi(targetEnumType target) is overriden,
// the right locApi should get created.
LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
                               ContextBase* context, bool isMaster,
                               LocAdapterProxyBase *adapterProxyBase,
                               bool waitForDoneInit) :
    mIsMaster(isMaster), mEvtMask(mask), mContext(context),
    mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase),
    mMsgTask(context->getMsgTask()),
    mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown)
{
    LOC_LOGd("waitForDoneInit: %d", waitForDoneInit);
    if (!waitForDoneInit) {
        mLocApi->addAdapter(this);
        mAdapterAdded = true;
    } else {
        mAdapterAdded = false;
    }
}

uint32_t LocAdapterBase::mSessionIdCounter(1);

uint32_t LocAdapterBase::generateSessionId()
{
    if (++mSessionIdCounter == 0xFFFFFFFF)
        mSessionIdCounter = 1;

     return mSessionIdCounter;
}

void LocAdapterBase::handleEngineUpEvent()
{
    if (mLocAdapterProxyBase) {
        mLocAdapterProxyBase->handleEngineUpEvent();
    }
}

void LocAdapterBase::handleEngineDownEvent()
{
    if (mLocAdapterProxyBase) {
        mLocAdapterProxyBase->handleEngineDownEvent();
    }
}

void LocAdapterBase::
    reportPositionEvent(const UlpLocation& location,
                        const GpsLocationExtended& locationExtended,
                        enum loc_sess_status status,
                        LocPosTechMask loc_technology_mask,
                        GnssDataNotification* /*pDataNotify*/,
                        int /*msInWeek*/)
{
    if (mLocAdapterProxyBase != NULL) {
        mLocAdapterProxyBase->reportPositionEvent((UlpLocation&)location,
                                                   (GpsLocationExtended&)locationExtended,
                                                   status,
                                                   loc_technology_mask);
    } else {
        DEFAULT_IMPL()
    }
}

void LocAdapterBase::
    reportSvEvent(const GnssSvNotification& /*svNotify*/,
                  bool /*fromEngineHub*/)
DEFAULT_IMPL()

void LocAdapterBase::
    reportSvPolynomialEvent(GnssSvPolynomial &/*svPolynomial*/)
DEFAULT_IMPL()

void LocAdapterBase::
    reportSvEphemerisEvent(GnssSvEphemerisReport &/*svEphemeris*/)
DEFAULT_IMPL()

void LocAdapterBase::
    reportStatus(LocGpsStatusValue /*status*/)
DEFAULT_IMPL()

void LocAdapterBase::
    reportNmeaEvent(const char* /*nmea*/, size_t /*length*/)
DEFAULT_IMPL()

void LocAdapterBase::
    reportDataEvent(const GnssDataNotification& /*dataNotify*/,
                    int /*msInWeek*/)
DEFAULT_IMPL()

bool LocAdapterBase::
    reportXtraServer(const char* /*url1*/, const char* /*url2*/,
                     const char* /*url3*/, const int /*maxlength*/)
DEFAULT_IMPL(false)

void LocAdapterBase::
    reportLocationSystemInfoEvent(const LocationSystemInfo& /*locationSystemInfo*/)
DEFAULT_IMPL()

bool LocAdapterBase::
    requestXtraData()
DEFAULT_IMPL(false)

bool LocAdapterBase::
    requestTime()
DEFAULT_IMPL(false)

bool LocAdapterBase::
    requestLocation()
DEFAULT_IMPL(false)

bool LocAdapterBase::
    requestATL(int /*connHandle*/, LocAGpsType /*agps_type*/,
               LocApnTypeMask /*apn_type_mask*/)
DEFAULT_IMPL(false)

bool LocAdapterBase::
    releaseATL(int /*connHandle*/)
DEFAULT_IMPL(false)

bool LocAdapterBase::
    requestNiNotifyEvent(const GnssNiNotification &/*notify*/,
                         const void* /*data*/,
                         const LocInEmergency /*emergencyState*/)
DEFAULT_IMPL(false)

void LocAdapterBase::
reportGnssMeasurementsEvent(const GnssMeasurements& /*gnssMeasurements*/,
                                   int /*msInWeek*/)
DEFAULT_IMPL()

bool LocAdapterBase::
    reportWwanZppFix(LocGpsLocation &/*zppLoc*/)
DEFAULT_IMPL(false)

bool LocAdapterBase::
    reportZppBestAvailableFix(LocGpsLocation& /*zppLoc*/,
            GpsLocationExtended& /*location_extended*/, LocPosTechMask /*tech_mask*/)
DEFAULT_IMPL(false)

void LocAdapterBase::reportGnssSvIdConfigEvent(const GnssSvIdConfig& /*config*/)
DEFAULT_IMPL()

void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/)
DEFAULT_IMPL()

void LocAdapterBase::reportGnssConfigEvent(uint32_t,  /* session id*/
            const GnssConfig& /*gnssConfig*/)
DEFAULT_IMPL()

bool LocAdapterBase::
    requestOdcpiEvent(OdcpiRequestInfo& /*request*/)
DEFAULT_IMPL(false)

bool LocAdapterBase::
    reportGnssEngEnergyConsumedEvent(uint64_t /*energyConsumedSinceFirstBoot*/)
DEFAULT_IMPL(false)

bool LocAdapterBase::
    reportDeleteAidingDataEvent(GnssAidingData & /*aidingData*/)
DEFAULT_IMPL(false)

bool LocAdapterBase::
    reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& /*ionoModel*/)
DEFAULT_IMPL(false)

bool LocAdapterBase::
    reportGnssAdditionalSystemInfoEvent(GnssAdditionalSystemInfo& /*additionalSystemInfo*/)
DEFAULT_IMPL(false)

void LocAdapterBase::
    reportNfwNotificationEvent(GnssNfwNotification& /*notification*/)
DEFAULT_IMPL()

void
LocAdapterBase::geofenceBreachEvent(size_t /*count*/, uint32_t* /*hwIds*/, Location& /*location*/,
                                    GeofenceBreachType /*breachType*/, uint64_t /*timestamp*/)
DEFAULT_IMPL()

void
LocAdapterBase::geofenceStatusEvent(GeofenceStatusAvailable /*available*/)
DEFAULT_IMPL()

void
LocAdapterBase::reportLocationsEvent(const Location* /*locations*/, size_t /*count*/,
                                     BatchingMode /*batchingMode*/)
DEFAULT_IMPL()

void
LocAdapterBase::reportCompletedTripsEvent(uint32_t /*accumulated_distance*/)
DEFAULT_IMPL()

void
LocAdapterBase::reportBatchStatusChangeEvent(BatchingStatus /*batchStatus*/)
DEFAULT_IMPL()

void
LocAdapterBase::reportPositionEvent(UlpLocation& /*location*/,
                                    GpsLocationExtended& /*locationExtended*/,
                                    enum loc_sess_status /*status*/,
                                    LocPosTechMask /*loc_technology_mask*/)
DEFAULT_IMPL()

void
LocAdapterBase::saveClient(LocationAPI* client, const LocationCallbacks& callbacks)
{
    mClientData[client] = callbacks;
    updateClientsEventMask();
}

void
LocAdapterBase::eraseClient(LocationAPI* client)
{
    auto it = mClientData.find(client);
    if (it != mClientData.end()) {
        mClientData.erase(it);
    }
    updateClientsEventMask();
}

LocationCallbacks
LocAdapterBase::getClientCallbacks(LocationAPI* client)
{
    LocationCallbacks callbacks = {};
    auto it = mClientData.find(client);
    if (it != mClientData.end()) {
        callbacks = it->second;
    }
    return callbacks;
}

LocationCapabilitiesMask
LocAdapterBase::getCapabilities()
{
    LocationCapabilitiesMask mask = 0;

    if (isEngineCapabilitiesKnown()) {
        // time based tracking always supported
        mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT;
        if (ContextBase::isMessageSupported(
                LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)){
            mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT |
                    LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT;
        }
        if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
            mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
        }
        if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
            mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
        }
        // geofence always supported
        mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
        if (ContextBase::gnssConstellationConfig()) {
            mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT;
        }
        uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities();
        if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) {
            mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT;
        }
        if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) {
            mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT;
        }
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
            mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT;
        }
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
            mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT;
        }
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
            mask |= LOCATION_CAPABILITIES_AGPM_BIT;
        }
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY)) {
            mask |= LOCATION_CAPABILITIES_PRIVACY_BIT;
        }
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
            mask |= LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT;
        }
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ROBUST_LOCATION)) {
            mask |= LOCATION_CAPABILITIES_CONFORMITY_INDEX_BIT;
        }
        if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_EDGNSS)) {
            mask |= LOCATION_CAPABILITIES_EDGNSS_BIT;
        }
    } else {
        LOC_LOGE("%s]: attempt to get capabilities before they are known.", __func__);
    }

    return mask;
}

void
LocAdapterBase::broadcastCapabilities(LocationCapabilitiesMask mask)
{
    for (auto clientData : mClientData) {
        if (nullptr != clientData.second.capabilitiesCb) {
            clientData.second.capabilitiesCb(mask);
        }
    }
}

void
LocAdapterBase::updateClientsEventMask()
DEFAULT_IMPL()

void
LocAdapterBase::stopClientSessions(LocationAPI* /*client*/)
DEFAULT_IMPL()

void
LocAdapterBase::addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks)
{
    LOC_LOGD("%s]: client %p", __func__, client);

    struct MsgAddClient : public LocMsg {
        LocAdapterBase& mAdapter;
        LocationAPI* mClient;
        const LocationCallbacks mCallbacks;
        inline MsgAddClient(LocAdapterBase& adapter,
                            LocationAPI* client,
                            const LocationCallbacks& callbacks) :
            LocMsg(),
            mAdapter(adapter),
            mClient(client),
            mCallbacks(callbacks) {}
        inline virtual void proc() const {
            mAdapter.saveClient(mClient, mCallbacks);
        }
    };

    sendMsg(new MsgAddClient(*this, client, callbacks));
}

void
LocAdapterBase::removeClientCommand(LocationAPI* client,
                                removeClientCompleteCallback rmClientCb)
{
    LOC_LOGD("%s]: client %p", __func__, client);

    struct MsgRemoveClient : public LocMsg {
        LocAdapterBase& mAdapter;
        LocationAPI* mClient;
        removeClientCompleteCallback mRmClientCb;
        inline MsgRemoveClient(LocAdapterBase& adapter,
                               LocationAPI* client,
                               removeClientCompleteCallback rmCb) :
            LocMsg(),
            mAdapter(adapter),
            mClient(client),
            mRmClientCb(rmCb){}
        inline virtual void proc() const {
            mAdapter.stopClientSessions(mClient);
            mAdapter.eraseClient(mClient);
            if (nullptr != mRmClientCb) {
                (mRmClientCb)(mClient);
            }
        }
    };

    sendMsg(new MsgRemoveClient(*this, client, rmClientCb));
}

void
LocAdapterBase::requestCapabilitiesCommand(LocationAPI* client)
{
    LOC_LOGD("%s]: ", __func__);

    struct MsgRequestCapabilities : public LocMsg {
        LocAdapterBase& mAdapter;
        LocationAPI* mClient;
        inline MsgRequestCapabilities(LocAdapterBase& adapter,
                                      LocationAPI* client) :
            LocMsg(),
            mAdapter(adapter),
            mClient(client) {}
        inline virtual void proc() const {
            if (!mAdapter.isEngineCapabilitiesKnown()) {
                mAdapter.mPendingMsgs.push_back(new MsgRequestCapabilities(*this));
                return;
            }
            LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient);
            if (callbacks.capabilitiesCb != nullptr) {
                callbacks.capabilitiesCb(mAdapter.getCapabilities());
            }
        }
    };

    sendMsg(new MsgRequestCapabilities(*this, client));
}

void
LocAdapterBase::reportLatencyInfoEvent(const GnssLatencyInfo& /*gnssLatencyInfo*/)
DEFAULT_IMPL()

bool LocAdapterBase::
    reportQwesCapabilities(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)
DEFAULT_IMPL(false)

} // namespace loc_core


code:
/* Copyright (c) 2011-2014, 2016-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 LOC_API_ADAPTER_BASE_H
#define LOC_API_ADAPTER_BASE_H

#include <gps_extended.h>
#include <ContextBase.h>
#include <LocationAPI.h>
#include <map>

#define MIN_TRACKING_INTERVAL (100) // 100 msec

typedef struct LocationSessionKey {
    LocationAPI* client;
    uint32_t id;
    inline LocationSessionKey(LocationAPI* _client, uint32_t _id) :
        client(_client), id(_id) {}
} LocationSessionKey;
inline bool operator <(LocationSessionKey const& left, LocationSessionKey const& right) {
    return left.id < right.id || (left.id == right.id && left.client < right.client);
}
inline bool operator ==(LocationSessionKey const& left, LocationSessionKey const& right) {
    return left.id == right.id && left.client == right.client;
}
inline bool operator !=(LocationSessionKey const& left, LocationSessionKey const& right) {
    return left.id != right.id || left.client != right.client;
}

typedef void (*removeClientCompleteCallback)(LocationAPI* client);

namespace loc_core {

class LocAdapterProxyBase;

class LocAdapterBase {
private:
    static uint32_t mSessionIdCounter;
    const bool mIsMaster;
    bool mIsEngineCapabilitiesKnown = false;

protected:
    LOC_API_ADAPTER_EVENT_MASK_T mEvtMask;
    ContextBase* mContext;
    LocApiBase* mLocApi;
    LocAdapterProxyBase* mLocAdapterProxyBase;
    const MsgTask* mMsgTask;
    bool mAdapterAdded;

    inline LocAdapterBase(const MsgTask* msgTask) :
        mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL),
        mLocAdapterProxyBase(NULL), mMsgTask(msgTask), mAdapterAdded(false) {}

    /* ==== CLIENT ========================================================================= */
    typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
    ClientDataMap mClientData;
    std::vector<LocMsg*> mPendingMsgs; // For temporal storage of msgs before Open is completed
    /* ======== UTILITIES ================================================================== */
    void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
    void eraseClient(LocationAPI* client);
    LocationCallbacks getClientCallbacks(LocationAPI* client);
    LocationCapabilitiesMask getCapabilities();
    void broadcastCapabilities(LocationCapabilitiesMask mask);
    virtual void updateClientsEventMask();
    virtual void stopClientSessions(LocationAPI* client);

public:
    inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); }
    // When waitForDoneInit is not specified or specified as false,
    // handleEngineUpEvent may be called on the child adapter object from
    // a different thread before the constructor of the child
    // object finishes.
    //
    // If the handleEngineUpEvent relies on member variables of the constructor
    // of the child adapter to be initialized first, we need to specify the
    // waitForDoneInit to *TRUE* to delay handleEngineUpEvent to get called
    // until when the child adapter finishes its initialization and notify
    // LocAdapterBase via doneInit method.
    LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
                   ContextBase* context, bool isMaster = false,
                   LocAdapterProxyBase *adapterProxyBase = NULL,
                   bool waitForDoneInit = false);

    inline void doneInit() {
        if (!mAdapterAdded) {
            mLocApi->addAdapter(this);
            mAdapterAdded = true;
        }
    }

    inline LOC_API_ADAPTER_EVENT_MASK_T
        checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const {
        return mEvtMask & mask;
    }

    inline LOC_API_ADAPTER_EVENT_MASK_T getEvtMask() const {
        return mEvtMask;
    }

    inline void sendMsg(const LocMsg* msg) const {
        mMsgTask->sendMsg(msg);
    }

    inline void sendMsg(const LocMsg* msg) {
        mMsgTask->sendMsg(msg);
    }

    inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event,
                              loc_registration_mask_status status)
    {
        switch(status) {
            case (LOC_REGISTRATION_MASK_ENABLED):
                mEvtMask = mEvtMask | event;
                break;
            case (LOC_REGISTRATION_MASK_DISABLED):
                mEvtMask = mEvtMask &~ event;
                break;
            case (LOC_REGISTRATION_MASK_SET):
                mEvtMask = event;
                break;
        }
        mLocApi->updateEvtMask();
    }

    inline void updateNmeaMask(uint32_t mask)
    {
        mLocApi->updateNmeaMask(mask);
    }

    inline bool isFeatureSupported(uint8_t featureVal) {
        return ContextBase::isFeatureSupported(featureVal);
    }

    static uint32_t generateSessionId();

    inline bool isAdapterMaster() {
        return mIsMaster;
    }

    inline bool isEngineCapabilitiesKnown() { return mIsEngineCapabilitiesKnown;}
    inline void setEngineCapabilitiesKnown(bool value) { mIsEngineCapabilitiesKnown = value;}

    virtual void handleEngineUpEvent();
    virtual void handleEngineDownEvent();
    virtual void reportPositionEvent(const UlpLocation& location,
                                     const GpsLocationExtended& locationExtended,
                                     enum loc_sess_status status,
                                     LocPosTechMask loc_technology_mask,
                                     GnssDataNotification* pDataNotify = nullptr,
                                     int msInWeek = -1);
    virtual void reportEnginePositionsEvent(unsigned int count,
                                            EngineLocationInfo* locationArr) {
        (void)count;
        (void)locationArr;
    }
    virtual void reportSvEvent(const GnssSvNotification& svNotify,
                               bool fromEngineHub=false);
    virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek);
    virtual void reportNmeaEvent(const char* nmea, size_t length);
    virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
    virtual void reportSvEphemerisEvent(GnssSvEphemerisReport &svEphemeris);
    virtual void reportStatus(LocGpsStatusValue status);
    virtual bool reportXtraServer(const char* url1, const char* url2,
                                  const char* url3, const int maxlength);
    virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo);

    virtual bool requestXtraData();
    virtual bool requestTime();
    virtual bool requestLocation();
    virtual bool requestATL(int connHandle, LocAGpsType agps_type,
                            LocApnTypeMask apn_type_mask);
    virtual bool releaseATL(int connHandle);
    virtual bool requestNiNotifyEvent(const GnssNiNotification &notify, const void* data,
                                      const LocInEmergency emergencyState);
    inline virtual bool isInSession() { return false; }
    ContextBase* getContext() const { return mContext; }
    virtual void reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
                                                int msInWeek);
    virtual bool reportWwanZppFix(LocGpsLocation &zppLoc);
    virtual bool reportZppBestAvailableFix(LocGpsLocation &zppLoc,
            GpsLocationExtended &location_extended, LocPosTechMask tech_mask);
    virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
    virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
    virtual void reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig);
    virtual bool requestOdcpiEvent(OdcpiRequestInfo& request);
    virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
    virtual bool reportDeleteAidingDataEvent(GnssAidingData &aidingData);
    virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel);
    virtual bool reportGnssAdditionalSystemInfoEvent(
            GnssAdditionalSystemInfo& additionalSystemInfo);
    virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);

    virtual void geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
                                     GeofenceBreachType breachType, uint64_t timestamp);
    virtual void geofenceStatusEvent(GeofenceStatusAvailable available);

    virtual void reportPositionEvent(UlpLocation &location,
                                     GpsLocationExtended &locationExtended,
                                     enum loc_sess_status status,
                                     LocPosTechMask loc_technology_mask);

    virtual void reportLocationsEvent(const Location* locations, size_t count,
            BatchingMode batchingMode);
    virtual void reportCompletedTripsEvent(uint32_t accumulated_distance);
    virtual void reportBatchStatusChangeEvent(BatchingStatus batchStatus);

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

    virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo);
    virtual bool reportQwesCapabilities(
            const std::unordered_map<LocationQwesFeatureType, bool> &featureMap);
};

} // namespace loc_core

#endif //LOC_API_ADAPTER_BASE_H


code:
/* Copyright (c) 2014, 2016-2017 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 LOC_ADAPTER_PROXY_BASE_H
#define LOC_ADAPTER_PROXY_BASE_H

#include <ContextBase.h>
#include <gps_extended.h>

namespace loc_core {

class LocAdapterProxyBase {
private:
    LocAdapterBase *mLocAdapterBase;
protected:
    inline LocAdapterProxyBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
                               ContextBase* context, bool isMaster = false):
            mLocAdapterBase(new LocAdapterBase(mask, context, isMaster, this)) {
    }
    inline virtual ~LocAdapterProxyBase() {
        delete mLocAdapterBase;
    }
    inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event,
                              loc_registration_mask_status isEnabled) {
        mLocAdapterBase->updateEvtMask(event,isEnabled);
    }

    inline uint32_t generateSessionId() {
        return mLocAdapterBase->generateSessionId();
    }
public:
    inline ContextBase* getContext() const {
        return mLocAdapterBase->getContext();
    }

    inline virtual void handleEngineUpEvent() {};
    inline virtual void handleEngineDownEvent() {};
    inline virtual void reportPositionEvent(UlpLocation &location,
                                            GpsLocationExtended &locationExtended,
                                            enum loc_sess_status status,
                                            LocPosTechMask loc_technology_mask) {
        (void)location;
        (void)locationExtended;
        (void)status;
        (void)loc_technology_mask;
    }
};

} // namespace loc_core

#endif //LOC_ADAPTER_PROXY_BASE_H