Merge "Adding one level of context swith for Geofence_add"
diff --git a/android/1.0/android.hardware.gnss@1.0-service-qti.rc b/android/1.0/android.hardware.gnss@1.0-service-qti.rc
index b5da6f9..1fbd893 100644
--- a/android/1.0/android.hardware.gnss@1.0-service-qti.rc
+++ b/android/1.0/android.hardware.gnss@1.0-service-qti.rc
@@ -1,4 +1,4 @@
 service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service-qti
     class hal
     user gps
-    group system gps radio
+    group system gps radio vendor_qti_diag
diff --git a/android/1.1/android.hardware.gnss@1.1-service-qti.rc b/android/1.1/android.hardware.gnss@1.1-service-qti.rc
index 41b105b..bd65584 100644
--- a/android/1.1/android.hardware.gnss@1.1-service-qti.rc
+++ b/android/1.1/android.hardware.gnss@1.1-service-qti.rc
@@ -1,4 +1,4 @@
 service gnss_service /vendor/bin/hw/android.hardware.gnss@1.1-service-qti
     class hal
     user gps
-    group system gps radio
+    group system gps radio vendor_qti_diag
diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp
index 084b6bf..b602989 100644
--- a/core/ContextBase.cpp
+++ b/core/ContextBase.cpp
@@ -40,6 +40,10 @@
 
 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;
@@ -80,6 +84,7 @@
   {"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'},
 };
 
 const loc_param_s_type ContextBase::mSap_conf_table[] =
@@ -171,10 +176,16 @@
         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 QCOM GNSS H/W */
+        mGps_conf.GNSS_DEPLOYMENT = 0;
 
         UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table);
         UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table);
 
+        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:
@@ -231,19 +242,24 @@
 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;
-            //try to see if LocApiV02 is present
-            if ((handle = dlopen("libloc_api_v02.so", RTLD_NOW)) != NULL) {
-                LOC_LOGD("%s:%d]: libloc_api_v02.so is present", __func__, __LINE__);
+
+            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 for LocApiV02", __func__,
-                            __LINE__);
+                    LOC_LOGD("%s:%d]: getter is not NULL of %s", __func__,
+                            __LINE__, libname);
                     locApi = (*getter)(exMask, this);
                 }
             }
diff --git a/core/ContextBase.h b/core/ContextBase.h
index ab61a08..5da76e2 100644
--- a/core/ContextBase.h
+++ b/core/ContextBase.h
@@ -73,6 +73,7 @@
     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;
 } loc_gps_cfg_s_type;
 
 /* NOTE: the implementaiton of the parser casts number
diff --git a/core/EngineHubProxyBase.h b/core/EngineHubProxyBase.h
index 4239a50..ec881f6 100644
--- a/core/EngineHubProxyBase.h
+++ b/core/EngineHubProxyBase.h
@@ -103,12 +103,8 @@
     }
 };
 
-typedef std::function<void(const UlpLocation& ulpLocation,
-                           const GpsLocationExtended& locationExtended,
-                           enum loc_sess_status status,
-                           LocPosTechMask techMask,
-                           bool fromEngineHub)>
-        GnssAdapterReportPositionEventCb;
+typedef std::function<void(int count, EngineLocationInfo* locationArr)>
+        GnssAdapterReportEnginePositionsEventCb;
 
 typedef std::function<void(const GnssSvNotification& svNotify,
                            bool fromEngineHub)>
@@ -119,11 +115,12 @@
 
 // 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,
-                                               GnssAdapterReportPositionEventCb positionEventCb,
-                                               GnssAdapterReportSvEventCb svEventCb,
-                                               GnssAdapterReqAidingDataCb reqAidingDataCb);
+typedef EngineHubProxyBase* (getEngHubProxyFn)(
+        const MsgTask * msgTask,
+        IOsObserver* osObserver,
+        GnssAdapterReportEnginePositionsEventCb positionEventCb,
+        GnssAdapterReportSvEventCb svEventCb,
+        GnssAdapterReqAidingDataCb reqAidingDataCb);
 
 } // namespace loc_core
 
diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp
index ffd3d5a..1b844e5 100644
--- a/core/LocAdapterBase.cpp
+++ b/core/LocAdapterBase.cpp
@@ -81,7 +81,6 @@
                         const GpsLocationExtended& locationExtended,
                         enum loc_sess_status status,
                         LocPosTechMask loc_technology_mask,
-                        bool /*fromEngineHub*/,
                         GnssDataNotification* pDataNotify,
                         int msInWeek)
 {
diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h
index b9b1f1e..909b6fe 100644
--- a/core/LocAdapterBase.h
+++ b/core/LocAdapterBase.h
@@ -151,9 +151,13 @@
                                      const GpsLocationExtended& locationExtended,
                                      enum loc_sess_status status,
                                      LocPosTechMask loc_technology_mask,
-                                     bool fromEngineHub = false,
                                      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);
diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp
index 14472fa..8c79cf7 100644
--- a/core/LocApiBase.cpp
+++ b/core/LocApiBase.cpp
@@ -345,7 +345,6 @@
     TO_ALL_LOCADAPTERS(
         mLocAdapters[i]->reportPositionEvent(location, locationExtended,
                                              status, loc_technology_mask,
-                                             false,
                                              pDataNotify, msInWeek)
     );
 }
diff --git a/etc/gps.conf b/etc/gps.conf
index f773e81..c247cbd 100644
--- a/etc/gps.conf
+++ b/etc/gps.conf
@@ -287,3 +287,13 @@
 #####################################
 # CP MTLR ES, 1=enable, 0=disable
 CP_MTLR_ES=0
+
+##################################################
+# GNSS_DEPLOYMENT
+##################################################
+# 0 : Enable QCOM GNSS (default)
+# 1 : Enable QCSR SS5
+# This setting use to select between QCOM GNSS
+# and QCSR SS5 hardware receiver.
+# By default QCOM GNSS receiver is enabled.
+# GNSS_DEPLOYMENT = 0
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index 7329638..578953d 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -484,6 +484,16 @@
         out.flags |= GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT;
         out.calibrationStatus = locationExtended.calibrationStatus;
     }
+
+    if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & locationExtended.flags) {
+        out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT;
+        out.locOutputEngType = locationExtended.locOutputEngType;
+    }
+
+    if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK & locationExtended.flags) {
+        out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT;
+        out.locOutputEngMask = locationExtended.locOutputEngMask;
+    }
 }
 
 
@@ -3054,32 +3064,23 @@
                                  const GpsLocationExtended& locationExtended,
                                  enum loc_sess_status status,
                                  LocPosTechMask techMask,
-                                 bool fromEngineHub,
                                  GnssDataNotification* pDataNotify,
                                  int msInWeek)
 {
-    // if this event is called from QMI LOC API, then send report to engine hub
+    // this position is from QMI LOC API, then send report to engine hub
     // if sending is successful, we return as we will wait for final report from engine hub
     // if the position is called from engine hub, then send it out directly
-    if (!fromEngineHub) {
-        // report QMI position (both propagated and unpropagated) to engine hub,
-        // and engine hub will be distributing it to the registered plugins
+
+    if (true == initEngHubProxy()){
         mEngHubProxy->gnssReportPosition(ulpLocation, locationExtended, status);
-
-        if (true == ulpLocation.unpropagatedPosition) {
-            return;
-        }
-
-        // engine hub is loaded, do not report qmi position to client as
-        // final position report should come from engine hub
-        if (true == initEngHubProxy()){
-            return;
-        }
+        return;
     }
 
-    // for all other cases:
-    // case 1: fix is from engine hub, queue the msg
-    // case 2: fix is not from engine hub, e.g. from QMI, and it is not an
+    if (true == ulpLocation.unpropagatedPosition) {
+        return;
+    }
+
+    // Fix is from QMI, and it is not an
     // unpropagated position and engine hub is not loaded, queue the msg
     // when message is queued, the position can be dispatched to requesting client
     struct MsgReportPosition : public LocMsg {
@@ -3136,6 +3137,35 @@
                                   pDataNotify, msInWeek));
 }
 
+void
+GnssAdapter::reportEnginePositionsEvent(unsigned int count,
+                                        EngineLocationInfo* locationArr)
+{
+    struct MsgReportEnginePositions : public LocMsg {
+        GnssAdapter& mAdapter;
+        unsigned int mCount;
+        EngineLocationInfo mEngLocInfo[LOC_OUTPUT_ENGINE_COUNT];
+        inline MsgReportEnginePositions(GnssAdapter& adapter,
+                                        unsigned int count,
+                                        EngineLocationInfo* locationArr) :
+            LocMsg(),
+            mAdapter(adapter),
+            mCount(count) {
+            if (mCount > LOC_OUTPUT_ENGINE_COUNT) {
+                mCount = LOC_OUTPUT_ENGINE_COUNT;
+            }
+            if (mCount > 0) {
+                memcpy(mEngLocInfo, locationArr, sizeof(EngineLocationInfo)*mCount);
+            }
+        }
+        inline virtual void proc() const {
+            mAdapter.reportEnginePositions(mCount, mEngLocInfo);
+        }
+    };
+
+    sendMsg(new MsgReportEnginePositions(*this, count, locationArr));
+}
+
 bool
 GnssAdapter::needReportForGnssClient(const UlpLocation& ulpLocation,
                                      enum loc_sess_status status,
@@ -3190,9 +3220,20 @@
 
         for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
             if ((reportToFlpClient && isFlpClient(it->second)) ||
-               (reportToGnssClient && !isFlpClient(it->second))) {
+                    (reportToGnssClient && !isFlpClient(it->second))) {
                 if (nullptr != it->second.gnssLocationInfoCb) {
                     it->second.gnssLocationInfoCb(locationInfo);
+                } else if ((nullptr != it->second.engineLocationsInfoCb) &&
+                        (false == initEngHubProxy())) {
+                    // if engine hub is disabled, this is SPE fix from modem
+                    // we need to mark one copy marked as fused and one copy marked as PPE
+                    // and dispatch it to the engineLocationsInfoCb
+                    GnssLocationInfoNotification engLocationsInfo[2];
+                    engLocationsInfo[0] = locationInfo;
+                    engLocationsInfo[0].locOutputEngType = LOC_OUTPUT_ENGINE_FUSED;
+                    engLocationsInfo[0].flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT;
+                    engLocationsInfo[1] = locationInfo;
+                    it->second.engineLocationsInfoCb(2, engLocationsInfo);
                 } else if (nullptr != it->second.trackingCb) {
                     it->second.trackingCb(locationInfo.location);
                 }
@@ -3241,6 +3282,48 @@
 }
 
 void
+GnssAdapter::reportEnginePositions(unsigned int count,
+                                   const EngineLocationInfo* locationArr)
+{
+    bool needReportEnginePositions = false;
+    for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+        if (nullptr != it->second.engineLocationsInfoCb) {
+            needReportEnginePositions = true;
+            break;
+        }
+    }
+
+    GnssLocationInfoNotification locationInfo[LOC_OUTPUT_ENGINE_COUNT] = {};
+    for (unsigned int i = 0; i < count; i++) {
+        const EngineLocationInfo* engLocation = (locationArr+i);
+        // if it is fused/default location, call reportPosition maintain legacy behavior
+        if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
+            (LOC_OUTPUT_ENGINE_FUSED == engLocation->locationExtended.locOutputEngType)) {
+            reportPosition(engLocation->location,
+                           engLocation->locationExtended,
+                           engLocation->sessionStatus,
+                           engLocation->location.tech_mask);
+        }
+
+        if (needReportEnginePositions) {
+            convertLocationInfo(locationInfo[i], engLocation->locationExtended);
+            convertLocation(locationInfo[i].location,
+                            engLocation->location,
+                            engLocation->locationExtended,
+                            engLocation->location.tech_mask);
+        }
+    }
+
+    if (needReportEnginePositions) {
+        for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+            if (nullptr != it->second.engineLocationsInfoCb) {
+                it->second.engineLocationsInfoCb(count, locationInfo);
+            }
+        }
+    }
+}
+
+void
 GnssAdapter::reportSvEvent(const GnssSvNotification& svNotify,
                            bool fromEngineHub)
 {
@@ -4913,15 +4996,10 @@
 
         // prepare the callback functions
         // callback function for engine hub to report back position event
-        GnssAdapterReportPositionEventCb reportPositionEventCb =
-            [this](const UlpLocation& ulpLocation,
-                   const GpsLocationExtended& locationExtended,
-                   enum loc_sess_status status,
-                   LocPosTechMask techMask,
-                   bool fromEngineHub) {
+        GnssAdapterReportEnginePositionsEventCb reportPositionEventCb =
+            [this](int count, EngineLocationInfo* locationArr) {
                     // report from engine hub on behalf of PPE will be treated as fromUlp
-                    reportPositionEvent(ulpLocation, locationExtended, status,
-                                        techMask, fromEngineHub);
+                    reportEnginePositionsEvent(count, locationArr);
             };
 
         // callback function for engine hub to report back sv event
diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h
index 410a4b7..3ccdd96 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -350,9 +350,11 @@
                                      const GpsLocationExtended& locationExtended,
                                      enum loc_sess_status status,
                                      LocPosTechMask techMask,
-                                     bool fromEngineHub = false,
                                      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);
@@ -385,6 +387,8 @@
                         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);
diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp
index a43178d..4348c27 100644
--- a/location/LocationAPI.cpp
+++ b/location/LocationAPI.cpp
@@ -85,6 +85,7 @@
     return (locationCallbacks.gnssNiCb != nullptr ||
             locationCallbacks.trackingCb != nullptr ||
             locationCallbacks.gnssLocationInfoCb != nullptr ||
+            locationCallbacks.engineLocationsInfoCb != nullptr ||
             locationCallbacks.gnssMeasurementsCb != nullptr);
 }
 
diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h
index 49822fa..27c5157 100644
--- a/location/LocationDataTypes.h
+++ b/location/LocationDataTypes.h
@@ -175,6 +175,8 @@
     GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT      = (1<<24), // number of SV used in position
     GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT       = (1<<25), // valid sensor cal confidence
     GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT           = (1<<26), // valid sensor cal status
+    GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT              = (1<<27), // valid output engine type
+    GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT              = (1<<28), // valid output engine mask
 } GnssLocationInfoFlagBits;
 
 typedef enum {
@@ -646,6 +648,13 @@
     GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES = 20    /**<  Maximum number of signal types */
 } Gnss_LocSignalEnumType;
 
+typedef uint32_t PositioningEngineMask;
+typedef enum {
+    STANDARD_POSITIONING_ENGINE = (1 << 0),
+    DEAD_RECKONING_ENGINE       = (1 << 1),
+    PRECISE_POSITIONING_ENGINE  = (1 << 2)
+} PositioningEngineBits;
+
 typedef uint64_t GnssDataMask;
 typedef enum {
     // Jammer Indicator is available
@@ -731,15 +740,35 @@
     LocationSpoofMask      spoofMask;
 } Location;
 
+typedef enum {
+    LOC_REQ_ENGINE_FUSED_BIT = (1<<0),
+    LOC_REQ_ENGINE_SPE_BIT   = (1<<1),
+    LOC_REQ_ENGINE_PPE_BIT   = (1<<2),
+} LocReqEngineTypeMask;
+
+typedef enum {
+    LOC_OUTPUT_ENGINE_FUSED   = 0,
+    /** This is the GNSS fix from modem */
+    LOC_OUTPUT_ENGINE_SPE     = 1,
+    /** This is the GNSS fix with correction PPP/RTK correction */
+    LOC_OUTPUT_ENGINE_PPE     = 2,
+    LOC_OUTPUT_ENGINE_COUNT,
+} LocOutputEngineType;
+
 struct LocationOptions {
     uint32_t size;          // set to sizeof(LocationOptions)
     uint32_t minInterval; // in milliseconds
     uint32_t minDistance; // in meters. if minDistance > 0, gnssSvCallback/gnssNmeaCallback/
                           // gnssMeasurementsCallback may not be called
     GnssSuplMode mode;    // Standalone/MS-Based/MS-Assisted
+    // behavior when this field is 0:
+    //  if engine hub is running, this will be fused fix,
+    //  if engine hub is not running, this will be SPE fix
+    LocReqEngineTypeMask locReqEngTypeMask;
 
     inline LocationOptions() :
-            size(0), minInterval(0), minDistance(0), mode(GNSS_SUPL_MODE_STANDALONE) {}
+            size(0), minInterval(0), minDistance(0), mode(GNSS_SUPL_MODE_STANDALONE),
+            locReqEngTypeMask((LocReqEngineTypeMask)0) {}
 };
 
 typedef enum {
@@ -764,9 +793,11 @@
     inline TrackingOptions(const LocationOptions& options) :
             LocationOptions(options), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {}
     inline void setLocationOptions(const LocationOptions& options) {
+        size = sizeof(TrackingOptions);
         minInterval = options.minInterval;
         minDistance = options.minDistance;
         mode = options.mode;
+        locReqEngTypeMask = options.locReqEngTypeMask;
     }
     inline LocationOptions getLocationOptions() {
         LocationOptions locOption;
@@ -774,6 +805,7 @@
         locOption.minDistance = minDistance;
         locOption.minInterval = minInterval;
         locOption.mode = mode;
+        locOption.locReqEngTypeMask = locReqEngTypeMask;
         return locOption;
     }
 };
@@ -997,6 +1029,16 @@
     uint8_t calibrationConfidence;                // Sensor calibration confidence percent,
                                                   // in range of [0, 100]
     DrCalibrationStatusMask calibrationStatus;    // Sensor calibration status
+    // location engine type. When the fix. when the type is set to
+    // LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated
+    // reports from all engines running on the system (e.g.:
+    // DR/SPE/PPE) based proprietary algorithm. To check which
+    // location engine contributes to the fused output, check for
+    // locOutputEngMask.
+    LocOutputEngineType locOutputEngType;
+    // when loc output eng type is set to fused, this field
+    // indicates the set of engines contribute to the fix.
+    PositioningEngineMask locOutputEngMask;
 } GnssLocationInfoNotification;
 
 typedef struct {
@@ -1317,6 +1359,20 @@
     GnssLocationInfoNotification gnssLocationInfoNotification
 )> gnssLocationInfoCallback;
 
+/* Gives default combined location information from all engines and
+   location information individually from selected engines.
+   This callback is only used when there are multiple engines
+   running in the system.
+
+   optional can be NULL
+
+   engineLocationsInfoCallback is called only during a tracking session
+   broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+    uint32_t count,
+    GnssLocationInfoNotification* engineLocationInfoNotification
+)> engineLocationsInfoCallback;
+
 /* Used for addGeofences API, optional can be NULL
    geofenceBreachCallback is called when any number of geofences have a state change */
 typedef std::function<void(
@@ -1403,6 +1459,7 @@
     gnssMeasurementsCallback gnssMeasurementsCb;     // optional
     batchingStatusCallback batchingStatusCb;         // optional
     locationSystemInfoCallback locationSystemInfoCb; // optional
+    engineLocationsInfoCallback engineLocationsInfoCb;     // optional
 } LocationCallbacks;
 
 #endif /* LOCATIONDATATYPES_H */
diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h
index 2036032..819e77b 100644
--- a/utils/gps_extended_c.h
+++ b/utils/gps_extended_c.h
@@ -384,6 +384,13 @@
 #define GPS_LOCATION_EXTENDED_HAS_CALIBRATION_CONFIDENCE 0x800000000
 /** GpsLocationExtended has sensor calibration status */
 #define GPS_LOCATION_EXTENDED_HAS_CALIBRATION_STATUS     0x1000000000
+/** GpsLocationExtended has the engine type that produced this
+ *  position, the bit mask will only be set when there are two
+ *  or more position engines running in the system */
+#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE       0x2000000000
+ /** GpsLocationExtended has the engine mask that indicates the
+  *     set of engines contribute to the fix. */
+#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK       0x4000000000
 
 typedef uint32_t LocNavSolutionMask;
 /* Bitmask to specify whether SBAS ionospheric correction is used  */
@@ -797,6 +804,16 @@
     /** Sensor calibration confidence percent. Range: 0 - 100 */
     uint8_t calibrationConfidence;
     DrCalibrationStatusMask calibrationStatus;
+    /* location engine type. When the fix. when the type is set to
+        LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated
+        reports from all engines running on the system (e.g.:
+        DR/SPE/PPE) based proprietary algorithm. To check which
+        location engine contributes to the fused output, check for
+        locOutputEngMask. */
+    LocOutputEngineType locOutputEngType;
+    /* when loc output eng type is set to fused, this field
+        indicates the set of engines contribute to the fix. */
+    PositioningEngineMask locOutputEngMask;
 } GpsLocationExtended;
 
 enum loc_sess_status {
@@ -805,6 +822,13 @@
     LOC_SESS_FAILURE
 };
 
+// struct that contains complete position info from engine
+typedef struct {
+    UlpLocation location;
+    GpsLocationExtended locationExtended;
+    enum loc_sess_status sessionStatus;
+} EngineLocationInfo;
+
 // Nmea sentence types mask
 typedef uint32_t NmeaSentenceTypesMask;
 #define LOC_NMEA_MASK_GGA_V02   ((NmeaSentenceTypesMask)0x00000001) /**<  Enable GGA type  */