Merge remote-tracking branch 'goog/qcom/release/LA.UM.8.1.R1.10.00.00.529.095' into qt-qpr1-dev am: b23301cfa5
am: d4d1b630d1

Change-Id: Ie515da7ba8355e467b0eb6aa14351ac02892403c
diff --git a/android/1.0/AGnss.cpp b/android/1.0/AGnss.cpp
index faaf75e..79f665c 100644
--- a/android/1.0/AGnss.cpp
+++ b/android/1.0/AGnss.cpp
@@ -105,7 +105,7 @@
 
     AgpsCbInfo cbInfo = {};
     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
-    cbInfo.cbPriority = AGPS_CB_PRIORITY_LOW;
+    cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
 
     mGnss->getGnssInterface()->agpsInit(cbInfo);
     return Void();
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/AGnss.cpp b/android/1.1/AGnss.cpp
index fe50c9a..d8f9706 100644
--- a/android/1.1/AGnss.cpp
+++ b/android/1.1/AGnss.cpp
@@ -105,7 +105,7 @@
 
     AgpsCbInfo cbInfo = {};
     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
-    cbInfo.cbPriority = AGPS_CB_PRIORITY_LOW;
+    cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
 
     mGnss->getGnssInterface()->agpsInit(cbInfo);
     return Void();
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/android/2.0/AGnss.cpp b/android/2.0/AGnss.cpp
index 7bd015e..a48f1a0 100644
--- a/android/2.0/AGnss.cpp
+++ b/android/2.0/AGnss.cpp
@@ -107,7 +107,7 @@
 
     AgpsCbInfo cbInfo = {};
     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
-    cbInfo.cbPriority = AGPS_CB_PRIORITY_HIGH;
+    cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
 
     mGnss->getGnssInterface()->agpsInit(cbInfo);
     return Void();
diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp
index 084b6bf..d5c3108 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 QTI 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 ef204ec..8c79cf7 100644
--- a/core/LocApiBase.cpp
+++ b/core/LocApiBase.cpp
@@ -148,7 +148,8 @@
     }
 };
 
-MsgTask* LocApiBase::mMsgTask;
+MsgTask* LocApiBase::mMsgTask = nullptr;
+volatile int32_t LocApiBase::mMsgTaskRefCount = 0;
 
 LocApiBase::LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
                        ContextBase* context) :
@@ -157,6 +158,7 @@
 {
     memset(mLocAdapters, 0, sizeof(mLocAdapters));
 
+    android_atomic_inc(&mMsgTaskRefCount);
     if (nullptr == mMsgTask) {
         mMsgTask = new MsgTask("LocApiMsgTask", false);
     }
@@ -230,7 +232,7 @@
     for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) {
         if (mLocAdapters[i] == NULL) {
             mLocAdapters[i] = adapter;
-            mMsgTask->sendMsg(new LocOpenMsg(this,  adapter));
+            sendMsg(new LocOpenMsg(this,  adapter));
             break;
         }
     }
@@ -263,10 +265,10 @@
 
             // if we have an empty list of adapters
             if (0 == i) {
-                mMsgTask->sendMsg(new LocCloseMsg(this));
+                sendMsg(new LocCloseMsg(this));
             } else {
                 // else we need to remove the bit
-                mMsgTask->sendMsg(new LocOpenMsg(this));
+                sendMsg(new LocOpenMsg(this));
             }
         }
     }
@@ -274,7 +276,7 @@
 
 void LocApiBase::updateEvtMask()
 {
-    mMsgTask->sendMsg(new LocOpenMsg(this));
+    sendMsg(new LocOpenMsg(this));
 }
 
 void LocApiBase::updateNmeaMask(uint32_t mask)
@@ -298,7 +300,7 @@
         }
     };
 
-    mMsgTask->sendMsg(new LocSetNmeaMsg(this, mask));
+    sendMsg(new LocSetNmeaMsg(this, mask));
 }
 
 void LocApiBase::handleEngineUpEvent()
@@ -343,7 +345,6 @@
     TO_ALL_LOCADAPTERS(
         mLocAdapters[i]->reportPositionEvent(location, locationExtended,
                                              status, loc_technology_mask,
-                                             false,
                                              pDataNotify, msInWeek)
     );
 }
diff --git a/core/LocApiBase.h b/core/LocApiBase.h
index 8c885f7..6dac585 100644
--- a/core/LocApiBase.h
+++ b/core/LocApiBase.h
@@ -34,6 +34,7 @@
 #include <gps_extended.h>
 #include <LocationAPI.h>
 #include <MsgTask.h>
+#include <LocSharedLock.h>
 #include <log_util.h>
 
 namespace loc_core {
@@ -107,6 +108,7 @@
     friend struct LocKillMsg;
     friend class ContextBase;
     static MsgTask* mMsgTask;
+    static volatile int32_t mMsgTaskRefCount;
     LocAdapterBase* mLocAdapters[MAX_ADAPTERS];
 
 protected:
@@ -121,7 +123,8 @@
     LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
                ContextBase* context = NULL);
     inline virtual ~LocApiBase() {
-        if (nullptr != mMsgTask) {
+        android_atomic_dec(&mMsgTaskRefCount);
+        if (nullptr != mMsgTask && 0 == mMsgTaskRefCount) {
             mMsgTask->destroy();
             mMsgTask = nullptr;
         }
@@ -132,7 +135,9 @@
 
 public:
     inline void sendMsg(const LocMsg* msg) const {
-        mMsgTask->sendMsg(msg);
+        if (nullptr != mMsgTask) {
+            mMsgTask->sendMsg(msg);
+        }
     }
     inline void destroy() {
         close();
diff --git a/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp
index 3fdb513..0427380 100644
--- a/core/SystemStatusOsObserver.cpp
+++ b/core/SystemStatusOsObserver.cpp
@@ -448,7 +448,7 @@
     }
 }
 
-#ifdef USE_QCMAP
+#ifdef USE_GLIB
 bool SystemStatusOsObserver::connectBackhaul()
 {
     bool result = false;
diff --git a/core/SystemStatusOsObserver.h b/core/SystemStatusOsObserver.h
index 8710976..fd60606 100644
--- a/core/SystemStatusOsObserver.h
+++ b/core/SystemStatusOsObserver.h
@@ -84,7 +84,7 @@
             mSystemStatus(systemstatus), mContext(msgTask, this),
             mAddress("SystemStatusOsObserver"),
             mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID)
-#ifdef USE_QCMAP
+#ifdef USE_GLIB
             , mBackHaulConnectReqCount(0)
 #endif
     {
@@ -106,7 +106,7 @@
     // To set the framework action request object
     inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) {
         mContext.mFrameworkActionReqObj = frameworkActionReqObj;
-#ifdef USE_QCMAP
+#ifdef USE_GLIB
         if (mBackHaulConnectReqCount > 0) {
             connectBackhaul();
             mBackHaulConnectReqCount = 0;
@@ -134,7 +134,7 @@
     // IFrameworkActionReq Overrides
     virtual void turnOn(DataItemId dit, int timeOut = 0) override;
     virtual void turnOff(DataItemId dit) override;
-#ifdef USE_QCMAP
+#ifdef USE_GLIB
     virtual bool connectBackhaul() override;
     virtual bool disconnectBackhaul();
 #endif
@@ -151,7 +151,7 @@
     // Cache the subscribe and requestData till subscription obj is obtained
     void cacheObserverRequest(ObserverReqCache& reqCache,
             const list<DataItemId>& l, IDataItemObserver* client);
-#ifdef USE_QCMAP
+#ifdef USE_GLIB
     // Cache the framework action request for connect/disconnect
     int         mBackHaulConnectReqCount;
 #endif
diff --git a/core/observer/IFrameworkActionReq.h b/core/observer/IFrameworkActionReq.h
index a4ccad8..4be947f 100644
--- a/core/observer/IFrameworkActionReq.h
+++ b/core/observer/IFrameworkActionReq.h
@@ -70,7 +70,7 @@
      */
     virtual void turnOff (DataItemId dit) = 0;
 
-#ifdef USE_QCMAP
+#ifdef USE_GLIB
     /**
      * @brief Setup WWAN backhaul
      * @details  Setup WWAN backhaul
diff --git a/etc/gps.conf b/etc/gps.conf
index 35a0a7e..fc37653 100644
--- a/etc/gps.conf
+++ b/etc/gps.conf
@@ -24,13 +24,6 @@
 # Intermediate position report, 1=enable, 0=disable
 INTERMEDIATE_POS=0
 
-# Below bit mask configures how GPS functionalities
-# should be locked when user turns off GPS on Settings
-# Set bit 0x1 if MO GPS functionalities are to be locked
-# Set bit 0x2 if NI GPS functionalities are to be locked
-# default – both MO and NI locked for maximal privacy
-#GPS_LOCK = 3
-
 # supl version 1.0
 SUPL_VER=0x10000
 
@@ -124,7 +117,7 @@
 # 0x2: WLAN AP Measurements for LPPe CP
 # 0x4: SRN AP measurement for CP
 # 0x8: Sensor Barometer Measurement LPPe CP
-LPPE_CP_TECHNOLOGY = 0
+#LPPE_CP_TECHNOLOGY = 0
 
 ##################################################
 # Select technology for LPPe User Plane
@@ -133,7 +126,7 @@
 # 0x2: WLAN AP Measurements for LPPe UP
 # 0x4: SRN AP measurement for UP
 # 0x8: Sensor Barometer Measurement LPPe UP
-LPPE_UP_TECHNOLOGY = 0
+#LPPE_UP_TECHNOLOGY = 0
 
 ##################################################
 # AGPS_CONFIG_INJECT
@@ -294,3 +287,13 @@
 #####################################
 # CP MTLR ES, 1=enable, 0=disable
 CP_MTLR_ES=0
+
+##################################################
+# GNSS_DEPLOYMENT
+##################################################
+# 0 : Enable QTI GNSS (default)
+# 1 : Enable QCSR SS5
+# This setting use to select between QTI GNSS
+# and QCSR SS5 hardware receiver.
+# By default QTI GNSS receiver is enabled.
+# GNSS_DEPLOYMENT = 0
diff --git a/geofence/GeofenceAdapter.cpp b/geofence/GeofenceAdapter.cpp
index b8746fb..e299589 100644
--- a/geofence/GeofenceAdapter.cpp
+++ b/geofence/GeofenceAdapter.cpp
@@ -242,30 +242,33 @@
                 if (NULL == mIds || NULL == mOptions || NULL == mInfos) {
                     errs[i] = LOCATION_ERROR_INVALID_PARAMETER;
                 } else {
-                    mApi.addGeofence(mIds[i],
-                             mOptions[i],
-                             mInfos[i],
-                             new LocApiResponseData<LocApiGeofenceData>(*mAdapter.getContext(),
-                                    [&mAdapter = mAdapter, mOptions = mOptions, mClient = mClient,
-                                    mCount = mCount, mIds = mIds, mInfos = mInfos, errs, i]
-                                    (LocationError err, LocApiGeofenceData data) {
-                        if (LOCATION_ERROR_SUCCESS == err) {
-                            mAdapter.saveGeofenceItem(mClient,
-                                                      mIds[i],
-                                                      data.hwId,
-                                                      mOptions[i],
-                                                      mInfos[i]);
-                        }
-                        errs[i] = err;
+                    mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+                            [&mAdapter = mAdapter, mCount = mCount, mClient = mClient,
+                            mOptions = mOptions, mInfos = mInfos, mIds = mIds, &mApi = mApi,
+                            errs, i] (LocationError err ) {
+                        mApi.addGeofence(mIds[i], mOptions[i], mInfos[i],
+                        new LocApiResponseData<LocApiGeofenceData>(*mAdapter.getContext(),
+                        [&mAdapter = mAdapter, mOptions = mOptions, mClient = mClient,
+                        mCount = mCount, mIds = mIds, mInfos = mInfos, errs, i]
+                        (LocationError err, LocApiGeofenceData data) {
+                            if (LOCATION_ERROR_SUCCESS == err) {
+                                mAdapter.saveGeofenceItem(mClient,
+                                mIds[i],
+                                data.hwId,
+                                mOptions[i],
+                                mInfos[i]);
+                            }
+                            errs[i] = err;
 
-                        // Send aggregated response on last item and cleanup
-                        if (i == mCount-1) {
-                            mAdapter.reportResponse(mClient, mCount, errs, mIds);
-                            delete[] errs;
-                            delete[] mIds;
-                            delete[] mOptions;
-                            delete[] mInfos;
-                        }
+                            // Send aggregated response on last item and cleanup
+                            if (i == mCount-1) {
+                                mAdapter.reportResponse(mClient, mCount, errs, mIds);
+                                delete[] errs;
+                                delete[] mIds;
+                                delete[] mOptions;
+                                delete[] mInfos;
+                            }
+                        }));
                     }));
                 }
             }
diff --git a/gnss/Agps.cpp b/gnss/Agps.cpp
index 7931d0c..9255f88 100644
--- a/gnss/Agps.cpp
+++ b/gnss/Agps.cpp
@@ -304,7 +304,7 @@
         nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN;
     }
 
-    mAgpsManager->mFrameworkStatusV4Cb(nifRequest);
+    mFrameworkStatusV4Cb(nifRequest);
 }
 
 void AgpsStateMachine::notifyAllSubscribers(
@@ -511,7 +511,7 @@
 
 /* CREATE AGPS STATE MACHINES
  * Must be invoked in Msg Handler context */
-void AgpsManager::createAgpsStateMachines() {
+void AgpsManager::createAgpsStateMachines(const AgpsCbInfo& cbInfo) {
 
     LOC_LOGD("AgpsManager::createAgpsStateMachines");
 
@@ -519,13 +519,16 @@
             ((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) ||
                     (loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB));
 
-    if (NULL == mInternetNif) {
+    if (NULL == mInternetNif && (cbInfo.atlType & AGPS_ATL_TYPE_WWAN)) {
         mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
+        mInternetNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
         LOC_LOGD("Internet NIF: %p", mInternetNif);
     }
     if (agpsCapable) {
-        if (NULL == mAgnssNif) {
+        if (NULL == mAgnssNif && (cbInfo.atlType & AGPS_ATL_TYPE_SUPL) &&
+                (cbInfo.atlType & AGPS_ATL_TYPE_SUPL_ES)) {
             mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
+            mAgnssNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
             LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
         }
     }
@@ -544,6 +547,11 @@
                 LOC_LOGE("NULL AGNSS NIF !");
             }
             return mAgnssNif;
+        case LOC_AGPS_TYPE_WWAN_ANY:
+            if (mInternetNif == NULL) {
+                LOC_LOGE("NULL Internet NIF !");
+            }
+            return mInternetNif;
         default:
             return mInternetNif;
     }
diff --git a/gnss/Agps.h b/gnss/Agps.h
index 829cbd5..d559377 100644
--- a/gnss/Agps.h
+++ b/gnss/Agps.h
@@ -137,6 +137,7 @@
     /* Current state for this state machine */
     AgpsState mState;
 
+    AgnssStatusIpV4Cb     mFrameworkStatusV4Cb;
 private:
     /* AGPS Type for this state machine
        LOC_AGPS_TYPE_ANY           0
@@ -154,6 +155,7 @@
 public:
     /* CONSTRUCTOR */
     AgpsStateMachine(AgpsManager* agpsManager, AGpsExtType agpsType):
+        mFrameworkStatusV4Cb(NULL),
         mAgpsManager(agpsManager), mSubscriberList(),
         mCurrentSubscriber(NULL), mState(AGPS_STATE_RELEASED),
         mAgpsType(agpsType), mAPN(NULL), mAPNLen(0),
@@ -175,6 +177,10 @@
     inline void setCurrentSubscriber(AgpsSubscriber* subscriber)
     { mCurrentSubscriber = subscriber; }
 
+    inline void registerFrameworkStatusCallback(AgnssStatusIpV4Cb frameworkStatusV4Cb) {
+        mFrameworkStatusV4Cb = frameworkStatusV4Cb;
+    }
+
     /* Fetch subscriber with specified handle */
     AgpsSubscriber* getSubscriber(int connHandle);
 
@@ -234,7 +240,6 @@
 public:
     /* CONSTRUCTOR */
     AgpsManager():
-        mFrameworkStatusV4Cb(NULL),
         mAtlOpenStatusCb(), mAtlCloseStatusCb(),
         mAgnssNif(NULL), mInternetNif(NULL)/*, mDsNif(NULL)*/ {}
 
@@ -246,12 +251,11 @@
         mAtlCloseStatusCb = atlCloseStatusCb;
     }
 
-    inline void registerFrameworkStatusCallback(AgnssStatusIpV4Cb frameworkStatusV4Cb) {
-        mFrameworkStatusV4Cb = frameworkStatusV4Cb;
-    }
+    /* Check if AGPS client is registered */
+    inline bool isRegistered() { return nullptr != mAgnssNif || nullptr != mInternetNif; }
 
     /* Create all AGPS state machines */
-    void createAgpsStateMachines();
+    void createAgpsStateMachines(const AgpsCbInfo& cbInfo);
 
     /* Process incoming ATL requests */
     void requestATL(int connHandle, AGpsExtType agpsType, LocApnTypeMask apnTypeMask);
@@ -266,7 +270,6 @@
     void handleModemSSR();
 
 protected:
-    AgnssStatusIpV4Cb     mFrameworkStatusV4Cb;
 
     AgpsAtlOpenStatusCb   mAtlOpenStatusCb;
     AgpsAtlCloseStatusCb  mAtlCloseStatusCb;
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index f3b459c..ad86606 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -80,7 +80,6 @@
     mGnssSvTypeConfigCb(nullptr),
     mNiData(),
     mAgpsManager(),
-    mAgpsCbInfo(),
     mOdcpiRequestCb(nullptr),
     mOdcpiRequestActive(false),
     mOdcpiTimer(this),
@@ -485,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;
+    }
 }
 
 
@@ -722,8 +731,6 @@
     //cache the injected configuration with GnssConfigRequested struct
     GnssConfig gnssConfigRequested = {};
     gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT |
-            GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT |
-            GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT |
             GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
     /* Here we process an SSR. We need to set the GPS_LOCK to the proper values, as follows:
     1. Q behavior. This is identified by mSupportNfwControl being 1. In this case
@@ -756,10 +763,17 @@
         gnssConfigRequested.aGlonassPositionProtocolMask =
                 gpsConf.A_GLONASS_POS_PROTOCOL_SELECT;
     }
-    gnssConfigRequested.lppeControlPlaneMask =
-            mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY);
-    gnssConfigRequested.lppeUserPlaneMask =
-            mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY);
+    if (gpsConf.LPPE_CP_TECHNOLOGY) {
+        gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
+        gnssConfigRequested.lppeControlPlaneMask =
+                mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY);
+    }
+
+    if (gpsConf.LPPE_UP_TECHNOLOGY) {
+        gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
+        gnssConfigRequested.lppeUserPlaneMask =
+                mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY);
+    }
     gnssConfigRequested.blacklistedSvIds.assign(mBlacklistedSvIds.begin(),
                                                 mBlacklistedSvIds.end());
     mLocApi->sendMsg(new LocApiMsg(
@@ -2079,10 +2093,9 @@
                 mask);
     }
 
-    if (mAgpsCbInfo.statusV4Cb != NULL) {
+    if (mAgpsManager.isRegistered()) {
         mask |= LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST;
     }
-
     // Add ODCPI handling
     if (nullptr != mOdcpiRequestCb) {
         mask |= LOC_API_ADAPTER_BIT_REQUEST_WIFI;
@@ -3052,32 +3065,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 {
@@ -3134,6 +3138,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,
@@ -3188,9 +3221,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);
                 }
@@ -3239,6 +3283,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)
 {
@@ -4112,27 +4198,17 @@
 /* INIT LOC AGPS MANAGER */
 
 void GnssAdapter::initAgps(const AgpsCbInfo& cbInfo) {
-    LOC_LOGD("%s]: mAgpsCbInfo.cbPriority - %d;  cbInfo.cbPriority - %d",
-            __func__, mAgpsCbInfo.cbPriority, cbInfo.cbPriority)
+    LOC_LOGD("%s]:cbInfo.atlType - %d", __func__, cbInfo.atlType);
 
     if (!((ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB) ||
             (ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA))) {
         return;
     }
 
-    if (mAgpsCbInfo.cbPriority > cbInfo.cbPriority) {
-        return;
-    } else {
-        mAgpsCbInfo = cbInfo;
-
-        mAgpsManager.registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
-
-        mAgpsManager.createAgpsStateMachines();
-
-        /* Register for AGPS event mask */
-        updateEvtMask(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST,
-                LOC_REGISTRATION_MASK_ENABLED);
-    }
+    mAgpsManager.createAgpsStateMachines(cbInfo);
+    /* Register for AGPS event mask */
+    updateEvtMask(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST,
+            LOC_REGISTRATION_MASK_ENABLED);
 }
 
 void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){
@@ -4921,15 +4997,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 b84c365..3ccdd96 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -163,7 +163,6 @@
     /* ==== AGPS =========================================================================== */
     // This must be initialized via initAgps()
     AgpsManager mAgpsManager;
-    AgpsCbInfo mAgpsCbInfo;
     void initAgps(const AgpsCbInfo& cbInfo);
 
     /* ==== NFW =========================================================================== */
@@ -351,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);
@@ -386,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/LocationAPIClientBase.h b/location/LocationAPIClientBase.h
index fddae60..098000c 100644
--- a/location/LocationAPIClientBase.h
+++ b/location/LocationAPIClientBase.h
@@ -488,6 +488,7 @@
             for (size_t i = 0; i < count; i++) {
                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
             }
+            LOC_LOGD("%s:]Returned geofence-id: %d in add geofence", __FUNCTION__, *ids);
             mAPI.onAddGeofencesCb(count, errors, ids);
             free(ids);
         }
@@ -505,6 +506,7 @@
                 for (size_t i = 0; i < count; i++) {
                     ids[i] = mRemovedGeofenceBiDict->getId(sessions[i]);
                 }
+                LOC_LOGD("%s:]Returned geofence-id: %d in remove geofence", __FUNCTION__, *ids);
                 mAPI.onRemoveGeofencesCb(count, errors, ids);
                 free(ids);
                 delete(mRemovedGeofenceBiDict);
diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h
index 49822fa..504b5cc 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,15 @@
     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). 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 +1358,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 +1458,7 @@
     gnssMeasurementsCallback gnssMeasurementsCb;     // optional
     batchingStatusCallback batchingStatusCb;         // optional
     locationSystemInfoCallback locationSystemInfoCb; // optional
+    engineLocationsInfoCallback engineLocationsInfoCb;     // optional
 } LocationCallbacks;
 
 #endif /* LOCATIONDATATYPES_H */
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 807916d..9a9c67e 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -29,6 +29,7 @@
         gps_extended.h \
         loc_gps.h \
         log_util.h \
+        LocSharedLock.h \
         LocUnorderedSetMap.h
 
 libgps_utils_la_c_sources = \
diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h
index b749783..69a659e 100644
--- a/utils/gps_extended_c.h
+++ b/utils/gps_extended_c.h
@@ -194,15 +194,14 @@
 /**<  Denotes APN type for emergency  */
 #define LOC_APN_TYPE_MASK_EMERGENCY ((LocApnTypeMask)0x00000200)
 
-typedef enum {
-    AGPS_CB_PRIORITY_LOW  = 1,
-    AGPS_CB_PRIORITY_MED  = 2,
-    AGPS_CB_PRIORITY_HIGH = 3
-} AgpsCbPriority;
+typedef uint32_t AGpsTypeMask;
+#define AGPS_ATL_TYPE_SUPL       ((AGpsTypeMask)0x00000001)
+#define AGPS_ATL_TYPE_SUPL_ES   ((AGpsTypeMask)0x00000002)
+#define AGPS_ATL_TYPE_WWAN       ((AGpsTypeMask)0x00000004)
 
 typedef struct {
     void* statusV4Cb;
-    AgpsCbPriority cbPriority;
+    AGpsTypeMask atlType;
 } AgpsCbInfo;
 
 typedef struct {
@@ -385,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  */
@@ -798,6 +804,15 @@
     /** 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). 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 {
@@ -806,6 +821,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  */
@@ -826,6 +848,20 @@
 #define LOC_NMEA_MASK_PQGSA_V02 ((NmeaSentenceTypesMask)0x00008000) /**<  Enable PQGSA type  */
 #define LOC_NMEA_MASK_PQGSV_V02 ((NmeaSentenceTypesMask)0x00010000) /**<  Enable PQGSV type  */
 #define LOC_NMEA_MASK_DEBUG_V02 ((NmeaSentenceTypesMask)0x00020000) /**<  Enable DEBUG type  */
+#define LOC_NMEA_MASK_GPDTM_V02 ((NmeaSentenceTypesMask)0x00040000) /**<  Enable GPDTM type  */
+#define LOC_NMEA_MASK_GNGGA_V02 ((NmeaSentenceTypesMask)0x00080000) /**<  Enable GNGGA type  */
+#define LOC_NMEA_MASK_GNRMC_V02 ((NmeaSentenceTypesMask)0x00100000) /**<  Enable GNRMC type  */
+#define LOC_NMEA_MASK_GNVTG_V02 ((NmeaSentenceTypesMask)0x00200000) /**<  Enable GNVTG type  */
+#define LOC_NMEA_MASK_GAGNS_V02 ((NmeaSentenceTypesMask)0x00400000) /**<  Enable GAGNS type  */
+#define LOC_NMEA_MASK_GBGGA_V02 ((NmeaSentenceTypesMask)0x00800000) /**<  Enable GBGGA type  */
+#define LOC_NMEA_MASK_GBGSA_V02 ((NmeaSentenceTypesMask)0x01000000) /**<  Enable GBGSA type  */
+#define LOC_NMEA_MASK_GBGSV_V02 ((NmeaSentenceTypesMask)0x02000000) /**<  Enable GBGSV type  */
+#define LOC_NMEA_MASK_GBRMC_V02 ((NmeaSentenceTypesMask)0x04000000) /**<  Enable GBRMC type  */
+#define LOC_NMEA_MASK_GBVTG_V02 ((NmeaSentenceTypesMask)0x08000000) /**<  Enable GBVTG type  */
+#define LOC_NMEA_MASK_GQGSV_V02 ((NmeaSentenceTypesMask)0x10000000) /**<  Enable GQGSV type  */
+#define LOC_NMEA_MASK_GIGSV_V02 ((NmeaSentenceTypesMask)0x20000000) /**<  Enable GIGSV type  */
+#define LOC_NMEA_MASK_GNDTM_V02 ((NmeaSentenceTypesMask)0x40000000) /**<  Enable GNDTM type  */
+
 
 // all bitmasks of general supported NMEA sentenses - debug is not part of this
 #define LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK  (LOC_NMEA_MASK_GGA_V02 | LOC_NMEA_MASK_RMC_V02 | \
@@ -833,7 +869,12 @@
         LOC_NMEA_MASK_PQXFI_V02 | LOC_NMEA_MASK_PSTIS_V02 | LOC_NMEA_MASK_GLGSV_V02 | \
         LOC_NMEA_MASK_GNGSA_V02 | LOC_NMEA_MASK_GNGNS_V02 | LOC_NMEA_MASK_GARMC_V02 | \
         LOC_NMEA_MASK_GAGSV_V02 | LOC_NMEA_MASK_GAGSA_V02 | LOC_NMEA_MASK_GAVTG_V02 | \
-        LOC_NMEA_MASK_GAGGA_V02 | LOC_NMEA_MASK_PQGSA_V02 | LOC_NMEA_MASK_PQGSV_V02)
+        LOC_NMEA_MASK_GAGGA_V02 | LOC_NMEA_MASK_PQGSA_V02 | LOC_NMEA_MASK_PQGSV_V02 | \
+        LOC_NMEA_MASK_GPDTM_V02 | LOC_NMEA_MASK_GNGGA_V02 | LOC_NMEA_MASK_GNRMC_V02 | \
+        LOC_NMEA_MASK_GNVTG_V02 | LOC_NMEA_MASK_GAGNS_V02 | LOC_NMEA_MASK_GBGGA_V02 | \
+        LOC_NMEA_MASK_GBGSA_V02 | LOC_NMEA_MASK_GBGSV_V02 | LOC_NMEA_MASK_GBRMC_V02 | \
+        LOC_NMEA_MASK_GBVTG_V02 | LOC_NMEA_MASK_GQGSV_V02 | LOC_NMEA_MASK_GIGSV_V02 | \
+        LOC_NMEA_MASK_GNDTM_V02)
 
 typedef enum {
   LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC = 0,
diff --git a/utils/loc_nmea.cpp b/utils/loc_nmea.cpp
index 2074e3e..41a707d 100644
--- a/utils/loc_nmea.cpp
+++ b/utils/loc_nmea.cpp
@@ -2076,5 +2076,13 @@
             loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
             GNSS_SIGNAL_BEIDOU_B2AI,false), nmeaArraystr);
 
+    // -----------------------------
+    // ------$GIGSV (NAVIC:L5)------
+    // -----------------------------
+
+    loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+            loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_NAVIC,
+            GNSS_SIGNAL_NAVIC_L5,false), nmeaArraystr);
+
     EXIT_LOG(%d, 0);
 }