FP5: gps/location: Update to LA.UM.9.14.1.r1-11900-QCM6490.QSSI14.0

Change-Id: I40672365d0e0d64a6081d427c417d9101af0748f
diff --git a/gps/Android.bp b/gps/Android.bp
index fb78f04..395136c 100644
--- a/gps/Android.bp
+++ b/gps/Android.bp
@@ -2,19 +2,3 @@
     "-Werror",
     "-Wno-undefined-bool-conversion",
 ]
-
-/* Activate the following for debug purposes only,
-   comment out for production */
-GNSS_SANITIZE_DIAG = {
-/*
-    diag: {
-        cfi: true,
-        misc_undefined: [
-            "bounds",
-            "null",
-            "unreachable",
-            "integer",
-        ],
-    },
-*/
-}
diff --git a/gps/Android.mk b/gps/Android.mk
index 60c9aa8..31841c4 100644
--- a/gps/Android.mk
+++ b/gps/Android.mk
@@ -23,6 +23,4 @@
 LOCAL_PATH := $(call my-dir)
 include $(call all-makefiles-under,$(LOCAL_PATH))
 
-GNSS_SANITIZE_DIAG := cfi bounds null unreachable integer address
-
 endif # ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
diff --git a/gps/android/1.0/AGnss.cpp b/gps/android/1.0/AGnss.cpp
index 79f665c..64a44a8 100644
--- a/gps/android/1.0/AGnss.cpp
+++ b/gps/android/1.0/AGnss.cpp
@@ -83,8 +83,11 @@
     }
     st.ipV4Addr = status.ipV4Addr;
 
-    if (mAGnssCbIface != nullptr) {
-        auto r = mAGnssCbIface->agnssStatusIpV4Cb(st);
+    mMutex.lock();
+    auto aGnssCbIface = mAGnssCbIface;
+    mMutex.unlock();
+    if (aGnssCbIface != nullptr) {
+        auto r = aGnssCbIface->agnssStatusIpV4Cb(st);
         if (!r.isOk()) {
             LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
         }
@@ -101,7 +104,9 @@
     }
 
     // Save the interface
+    mMutex.lock();
     mAGnssCbIface = callback;
+    mMutex.unlock();
 
     AgpsCbInfo cbInfo = {};
     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
diff --git a/gps/android/1.0/AGnss.h b/gps/android/1.0/AGnss.h
index cdd5931..1d4c58b 100644
--- a/gps/android/1.0/AGnss.h
+++ b/gps/android/1.0/AGnss.h
@@ -21,6 +21,7 @@
 #ifndef ANDROID_HARDWARE_GNSS_V1_0_AGNSS_H
 #define ANDROID_HARDWARE_GNSS_V1_0_AGNSS_H
 
+#include <mutex>
 #include <android/hardware/gnss/1.0/IAGnss.h>
 #include <hidl/Status.h>
 #include <gps_extended_c.h>
@@ -67,6 +68,7 @@
 
  private:
     Gnss* mGnss = nullptr;
+    std::mutex mMutex;
     sp<IAGnssCallback> mAGnssCbIface = nullptr;
 };
 
diff --git a/gps/android/1.0/AGnssRil.cpp b/gps/android/1.0/AGnssRil.cpp
index d7f30eb..e2d5948 100644
--- a/gps/android/1.0/AGnssRil.cpp
+++ b/gps/android/1.0/AGnssRil.cpp
@@ -29,7 +29,7 @@
 #include <string>
 #include "Gnss.h"
 #include "AGnssRil.h"
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 
 typedef void* (getLocationInterface)();
 
@@ -58,29 +58,29 @@
 
     // for XTRA
     if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
-        int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+        int8_t typeout = loc_core::TYPE_UNKNOWN;
         switch(type)
         {
             case IAGnssRil::NetworkType::MOBILE:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+                typeout = loc_core::TYPE_MOBILE;
                 break;
             case IAGnssRil::NetworkType::WIFI:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+                typeout = loc_core::TYPE_WIFI;
                 break;
             case IAGnssRil::NetworkType::MMS:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+                typeout = loc_core::TYPE_MMS;
                 break;
             case IAGnssRil::NetworkType::SUPL:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+                typeout = loc_core::TYPE_SUPL;
                 break;
             case IAGnssRil::NetworkType::DUN:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+                typeout = loc_core::TYPE_DUN;
                 break;
             case IAGnssRil::NetworkType::HIPRI:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+                typeout = loc_core::TYPE_HIPRI;
                 break;
             case IAGnssRil::NetworkType::WIMAX:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+                typeout = loc_core::TYPE_WIMAX;
                 break;
             default:
                 {
@@ -89,16 +89,16 @@
                     switch(networkType)
                     {
                         case NetworkType_BLUETOOTH:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+                            typeout = loc_core::TYPE_BLUETOOTH;
                             break;
                         case NetworkType_ETHERNET:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+                            typeout = loc_core::TYPE_ETHERNET;
                             break;
                         case NetworkType_PROXY:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+                            typeout = loc_core::TYPE_PROXY;
                             break;
                         default:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+                            typeout = loc_core::TYPE_UNKNOWN;
                     }
                 }
                 break;
diff --git a/gps/android/1.0/Android.mk b/gps/android/1.0/Android.mk
index f63a948..0c60fd4 100644
--- a/gps/android/1.0/Android.mk
+++ b/gps/android/1.0/Android.mk
@@ -3,8 +3,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti
 
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := \
@@ -59,8 +57,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@1.0-service-qti
 
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.0-service-qti.xml
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/gps/android/1.0/GnssMeasurement.cpp b/gps/android/1.0/GnssMeasurement.cpp
index 7af9e27..e24e1d2 100644
--- a/gps/android/1.0/GnssMeasurement.cpp
+++ b/gps/android/1.0/GnssMeasurement.cpp
@@ -18,11 +18,15 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #define LOG_TAG "LocSvc_GnssMeasurementInterface"
 
 #include <log_util.h>
-#include <MeasurementAPIClient.h>
-#include "GnssMeasurement.h"
+#include <GnssMeasurement.h>
 
 namespace android {
 namespace hardware {
@@ -52,44 +56,47 @@
 }
 
 // Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
-
-Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
         const sp<V1_0::IGnssMeasurementCallback>& callback)  {
+    return setCallback(callback, mGnssMeasurementCbIface, GNSS_POWER_MODE_INVALID);
+}
 
-    Return<IGnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
+template <typename T>
+Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+        const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode) {
+    Return<GnssMeasurement::GnssMeasurementStatus> ret =
+            IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
     if (mApi == nullptr) {
         LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
         return ret;
     }
+    if (myCallback != callback) {
+        if (nullptr == callback) {
+            LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+            mApi->measurementSetCallback(callback);
+            close();
+        } else {
+            if (nullptr != myCallback) {
+                myCallback->unlinkToDeath(mGnssMeasurementDeathRecipient);
+            }
+            myCallback = callback;
+            myCallback->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+            ret = mApi->measurementSetCallback(callback, powerMode);
+        }
+    }
 
-    mGnssMeasurementCbIface = callback;
-    mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    return mApi->measurementSetCallback(callback);
-
+    return ret;
 }
 
 Return<void> GnssMeasurement::close()  {
-    if (mApi == nullptr) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return Void();
+    if (mApi != nullptr) {
+        mApi->measurementSetCallback<V1_0::IGnssMeasurementCallback>(nullptr);
     }
 
     if (mGnssMeasurementCbIface != nullptr) {
         mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
         mGnssMeasurementCbIface = nullptr;
     }
-    mApi->measurementClose();
 
     return Void();
 }
diff --git a/gps/android/1.0/GnssMeasurement.h b/gps/android/1.0/GnssMeasurement.h
index 4247dbf..245c697 100644
--- a/gps/android/1.0/GnssMeasurement.h
+++ b/gps/android/1.0/GnssMeasurement.h
@@ -18,12 +18,18 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #ifndef ANDROID_HARDWARE_GNSS_V1_0_GNSSMEASUREMENT_H
 #define ANDROID_HARDWARE_GNSS_V1_0_GNSSMEASUREMENT_H
 
 #include <android/hardware/gnss/1.0/IGnssMeasurement.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include "MeasurementAPIClient.h"
 
 namespace android {
 namespace hardware {
@@ -62,7 +68,9 @@
         sp<GnssMeasurement> mGnssMeasurement;
     };
 
- private:
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> setCallback(
+            const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode);
     sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
     sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
     MeasurementAPIClient* mApi;
diff --git a/gps/android/1.0/location_api/MeasurementAPIClient.cpp b/gps/android/1.0/location_api/MeasurementAPIClient.cpp
index 9b23308..41ba582 100644
--- a/gps/android/1.0/location_api/MeasurementAPIClient.cpp
+++ b/gps/android/1.0/location_api/MeasurementAPIClient.cpp
@@ -63,19 +63,6 @@
     LOC_LOGD("%s]: ()", __FUNCTION__);
 }
 
-// for GpsInterface
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
-{
-    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
-
-    mMutex.lock();
-    mGnssMeasurementCbIface = callback;
-    mMutex.unlock();
-
-    return startTracking();
-}
-
 Return<IGnssMeasurement::GnssMeasurementStatus>
 MeasurementAPIClient::startTracking()
 {
@@ -83,16 +70,6 @@
     memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
     locationCallbacks.size = sizeof(LocationCallbacks);
 
-    locationCallbacks.trackingCb = nullptr;
-    locationCallbacks.batchingCb = nullptr;
-    locationCallbacks.geofenceBreachCb = nullptr;
-    locationCallbacks.geofenceStatusCb = nullptr;
-    locationCallbacks.gnssLocationInfoCb = nullptr;
-    locationCallbacks.gnssNiCb = nullptr;
-    locationCallbacks.gnssSvCb = nullptr;
-    locationCallbacks.gnssNmeaCb = nullptr;
-
-    locationCallbacks.gnssMeasurementsCb = nullptr;
     if (mGnssMeasurementCbIface != nullptr) {
         locationCallbacks.gnssMeasurementsCb =
             [this](GnssMeasurementsNotification gnssMeasurementsNotification) {
@@ -109,7 +86,7 @@
     options.mode = GNSS_SUPL_MODE_STANDALONE;
 
     mTracking = true;
-    LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+    LOC_LOGd();
     locAPIStartTracking(options);
     return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
 }
diff --git a/gps/android/1.0/location_api/MeasurementAPIClient.h b/gps/android/1.0/location_api/MeasurementAPIClient.h
index 225deac..1c86882 100644
--- a/gps/android/1.0/location_api/MeasurementAPIClient.h
+++ b/gps/android/1.0/location_api/MeasurementAPIClient.h
@@ -53,8 +53,15 @@
     MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
 
     // for GpsMeasurementInterface
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
-            const sp<V1_0::IGnssMeasurementCallback>& callback);
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+            const sp<T>& callback, GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID) {
+        mMutex.lock();
+        setCallbackLocked(callback);
+        mMutex.unlock();
+
+        return startTracking();
+    }
     void measurementClose();
     Return<IGnssMeasurement::GnssMeasurementStatus> startTracking();
 
@@ -62,6 +69,9 @@
     void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
 
 private:
+    inline void setCallbackLocked(const sp<V1_0::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface = callback;
+    }
     virtual ~MeasurementAPIClient();
 
     std::mutex mMutex;
diff --git a/gps/android/1.1/AGnss.cpp b/gps/android/1.1/AGnss.cpp
index d8f9706..c633cc1 100644
--- a/gps/android/1.1/AGnss.cpp
+++ b/gps/android/1.1/AGnss.cpp
@@ -83,8 +83,11 @@
     }
     st.ipV4Addr = status.ipV4Addr;
 
-    if (mAGnssCbIface != nullptr) {
-        auto r = mAGnssCbIface->agnssStatusIpV4Cb(st);
+    mMutex.lock();
+    auto aGnssCbIface = mAGnssCbIface;
+    mMutex.unlock();
+    if (aGnssCbIface != nullptr) {
+        auto r = aGnssCbIface->agnssStatusIpV4Cb(st);
         if (!r.isOk()) {
             LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
         }
@@ -101,7 +104,9 @@
     }
 
     // Save the interface
+    mMutex.lock();
     mAGnssCbIface = callback;
+    mMutex.unlock();
 
     AgpsCbInfo cbInfo = {};
     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
diff --git a/gps/android/1.1/AGnss.h b/gps/android/1.1/AGnss.h
index 4b599b9..1783b24 100644
--- a/gps/android/1.1/AGnss.h
+++ b/gps/android/1.1/AGnss.h
@@ -21,6 +21,7 @@
 #ifndef ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
 #define ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
 
+#include <mutex>
 #include <android/hardware/gnss/1.0/IAGnss.h>
 #include <hidl/Status.h>
 #include <gps_extended_c.h>
@@ -67,6 +68,7 @@
 
  private:
     Gnss* mGnss = nullptr;
+    std::mutex mMutex;
     sp<IAGnssCallback> mAGnssCbIface = nullptr;
 };
 
diff --git a/gps/android/1.1/AGnssRil.cpp b/gps/android/1.1/AGnssRil.cpp
index 95c8d63..26254e5 100644
--- a/gps/android/1.1/AGnssRil.cpp
+++ b/gps/android/1.1/AGnssRil.cpp
@@ -29,7 +29,7 @@
 #include <string>
 #include "Gnss.h"
 #include "AGnssRil.h"
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 
 typedef void* (getLocationInterface)();
 
@@ -58,29 +58,29 @@
 
     // for XTRA
     if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
-        int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+        int8_t typeout = loc_core::TYPE_UNKNOWN;
         switch(type)
         {
             case IAGnssRil::NetworkType::MOBILE:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+                typeout = loc_core::TYPE_MOBILE;
                 break;
             case IAGnssRil::NetworkType::WIFI:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+                typeout = loc_core::TYPE_WIFI;
                 break;
             case IAGnssRil::NetworkType::MMS:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+                typeout = loc_core::TYPE_MMS;
                 break;
             case IAGnssRil::NetworkType::SUPL:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+                typeout = loc_core::TYPE_SUPL;
                 break;
             case IAGnssRil::NetworkType::DUN:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+                typeout = loc_core::TYPE_DUN;
                 break;
             case IAGnssRil::NetworkType::HIPRI:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+                typeout = loc_core::TYPE_HIPRI;
                 break;
             case IAGnssRil::NetworkType::WIMAX:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+                typeout = loc_core::TYPE_WIMAX;
                 break;
             default:
                 {
@@ -89,16 +89,16 @@
                     switch(networkType)
                     {
                         case NetworkType_BLUETOOTH:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+                            typeout = loc_core::TYPE_BLUETOOTH;
                             break;
                         case NetworkType_ETHERNET:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+                            typeout = loc_core::TYPE_ETHERNET;
                             break;
                         case NetworkType_PROXY:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+                            typeout = loc_core::TYPE_PROXY;
                             break;
                         default:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+                            typeout = loc_core::TYPE_UNKNOWN;
                     }
                 }
                 break;
diff --git a/gps/android/1.1/Android.mk b/gps/android/1.1/Android.mk
index edf8547..27272ae 100644
--- a/gps/android/1.1/Android.mk
+++ b/gps/android/1.1/Android.mk
@@ -3,8 +3,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@1.1-impl-qti
 
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := \
@@ -60,8 +58,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@1.1-service-qti
 
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.1-service-qti.xml
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/gps/android/1.1/GnssMeasurement.cpp b/gps/android/1.1/GnssMeasurement.cpp
index 6f8c14d..4f35a49 100644
--- a/gps/android/1.1/GnssMeasurement.cpp
+++ b/gps/android/1.1/GnssMeasurement.cpp
@@ -18,10 +18,14 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #define LOG_TAG "LocSvc_GnssMeasurementInterface"
 
 #include <log_util.h>
-#include <MeasurementAPIClient.h>
 #include "GnssMeasurement.h"
 
 namespace android {
@@ -52,37 +56,42 @@
 }
 
 // Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
-
-Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
         const sp<V1_0::IGnssMeasurementCallback>& callback)  {
+    return setCallback(callback, mGnssMeasurementCbIface, GNSS_POWER_MODE_INVALID);
+}
 
-    Return<IGnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
+template <typename T>
+Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+        const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode) {
+    Return<GnssMeasurement::GnssMeasurementStatus> ret =
+            IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
     if (mApi == nullptr) {
         LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
         return ret;
     }
+    if (myCallback != callback) {
+        if (nullptr == callback) {
+            LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+            mApi->measurementSetCallback(callback);
+            close();
+        } else {
+            if (nullptr != myCallback) {
+                myCallback->unlinkToDeath(mGnssMeasurementDeathRecipient);
+            }
+            myCallback = callback;
+            myCallback->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+            ret = mApi->measurementSetCallback(callback, powerMode);
+        }
+    }
 
-    mGnssMeasurementCbIface = callback;
-    mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    return mApi->measurementSetCallback(callback);
-
+    return ret;
 }
 
 Return<void> GnssMeasurement::close()  {
-    if (mApi == nullptr) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return Void();
+    if (mApi != nullptr) {
+        mApi->measurementSetCallback<V1_0::IGnssMeasurementCallback>(nullptr);
+        mApi->measurementSetCallback<V1_1::IGnssMeasurementCallback>(nullptr);
     }
 
     if (mGnssMeasurementCbIface != nullptr) {
@@ -93,7 +102,6 @@
         mGnssMeasurementCbIface_1_1->unlinkToDeath(mGnssMeasurementDeathRecipient);
         mGnssMeasurementCbIface_1_1 = nullptr;
     }
-    mApi->measurementClose();
 
     return Void();
 }
@@ -101,30 +109,8 @@
 // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
 Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
         const sp<IGnssMeasurementCallback>& callback, bool enableFullTracking) {
-
-    Return<IGnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface_1_1 != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
-    if (nullptr == mApi) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return ret;
-    }
-
-    mGnssMeasurementCbIface_1_1 = callback;
-    mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    GnssPowerMode powerMode = enableFullTracking?
-            GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
-
-    return mApi->measurementSetCallback_1_1(callback, powerMode);
+    return setCallback(callback, mGnssMeasurementCbIface_1_1,
+                       enableFullTracking ? GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2);
 }
 
 }  // namespace implementation
diff --git a/gps/android/1.1/GnssMeasurement.h b/gps/android/1.1/GnssMeasurement.h
index 373f0d0..ccafff2 100644
--- a/gps/android/1.1/GnssMeasurement.h
+++ b/gps/android/1.1/GnssMeasurement.h
@@ -18,12 +18,18 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
 #define ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
 
 #include <android/hardware/gnss/1.1/IGnssMeasurement.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include "MeasurementAPIClient.h"
 
 namespace android {
 namespace hardware {
@@ -67,7 +73,9 @@
         sp<GnssMeasurement> mGnssMeasurement;
     };
 
- private:
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> setCallback(
+            const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode);
     sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
     sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
     sp<IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
diff --git a/gps/android/1.1/location_api/MeasurementAPIClient.cpp b/gps/android/1.1/location_api/MeasurementAPIClient.cpp
index a87ae6d..7764851 100644
--- a/gps/android/1.1/location_api/MeasurementAPIClient.cpp
+++ b/gps/android/1.1/location_api/MeasurementAPIClient.cpp
@@ -66,34 +66,6 @@
     LOC_LOGD("%s]: ()", __FUNCTION__);
 }
 
-// for GpsInterface
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
-{
-    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
-
-    mMutex.lock();
-    mGnssMeasurementCbIface = callback;
-    mMutex.unlock();
-
-    return startTracking();
-}
-
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback_1_1(
-        const sp<IGnssMeasurementCallback>& callback,
-        GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
-{
-    LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
-            __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
-
-    mMutex.lock();
-    mGnssMeasurementCbIface_1_1 = callback;
-    mMutex.unlock();
-
-    return startTracking(powerMode, timeBetweenMeasurement);
-}
-
 Return<IGnssMeasurement::GnssMeasurementStatus>
 MeasurementAPIClient::startTracking(
         GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
@@ -102,16 +74,6 @@
     memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
     locationCallbacks.size = sizeof(LocationCallbacks);
 
-    locationCallbacks.trackingCb = nullptr;
-    locationCallbacks.batchingCb = nullptr;
-    locationCallbacks.geofenceBreachCb = nullptr;
-    locationCallbacks.geofenceStatusCb = nullptr;
-    locationCallbacks.gnssLocationInfoCb = nullptr;
-    locationCallbacks.gnssNiCb = nullptr;
-    locationCallbacks.gnssSvCb = nullptr;
-    locationCallbacks.gnssNmeaCb = nullptr;
-
-    locationCallbacks.gnssMeasurementsCb = nullptr;
     if (mGnssMeasurementCbIface_1_1 != nullptr || mGnssMeasurementCbIface != nullptr) {
         locationCallbacks.gnssMeasurementsCb =
             [this](GnssMeasurementsNotification gnssMeasurementsNotification) {
@@ -132,7 +94,7 @@
     }
 
     mTracking = true;
-    LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+    LOC_LOGd("(powermode: %d) (tbm %d)", (int)powerMode, timeBetweenMeasurement);
     locAPIStartTracking(options);
     return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
 }
diff --git a/gps/android/1.1/location_api/MeasurementAPIClient.h b/gps/android/1.1/location_api/MeasurementAPIClient.h
index 5fb307c..e768e77 100644
--- a/gps/android/1.1/location_api/MeasurementAPIClient.h
+++ b/gps/android/1.1/location_api/MeasurementAPIClient.h
@@ -53,12 +53,15 @@
     MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
 
     // for GpsMeasurementInterface
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
-            const sp<V1_0::IGnssMeasurementCallback>& callback);
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
-            const sp<IGnssMeasurementCallback>& callback,
-            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
-            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+            const sp<T>& callback, GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID) {
+        mMutex.lock();
+        setCallbackLocked(callback);
+        mMutex.unlock();
+
+        return startTracking(powerMode);
+    }
     void measurementClose();
     Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
             GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
@@ -68,6 +71,12 @@
     void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
 
 private:
+    inline void setCallbackLocked(const sp<V1_0::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface = callback;
+    }
+    inline void setCallbackLocked(const sp<V1_1::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface_1_1 = callback;
+    }
     virtual ~MeasurementAPIClient();
 
     std::mutex mMutex;
diff --git a/gps/android/2.0/AGnss.cpp b/gps/android/2.0/AGnss.cpp
index a48f1a0..df2fe20 100644
--- a/gps/android/2.0/AGnss.cpp
+++ b/gps/android/2.0/AGnss.cpp
@@ -84,8 +84,11 @@
         return;
     }
 
-    if (mAGnssCbIface != nullptr) {
-        auto r = mAGnssCbIface->agnssStatusCb(aType, aStatus);
+    mMutex.lock();
+    auto aGnssCbIface = mAGnssCbIface;
+    mMutex.unlock();
+    if (aGnssCbIface != nullptr) {
+        auto r = aGnssCbIface->agnssStatusCb(aType, aStatus);
         if (!r.isOk()) {
             LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
         }
@@ -103,7 +106,9 @@
     }
 
     // Save the interface
+    mMutex.lock();
     mAGnssCbIface = callback;
+    mMutex.unlock();
 
     AgpsCbInfo cbInfo = {};
     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
diff --git a/gps/android/2.0/AGnss.h b/gps/android/2.0/AGnss.h
index c442327..ab653aa 100644
--- a/gps/android/2.0/AGnss.h
+++ b/gps/android/2.0/AGnss.h
@@ -21,6 +21,7 @@
 #ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
 #define ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
 
+#include <mutex>
 #include <android/hardware/gnss/2.0/IAGnss.h>
 #include <hidl/Status.h>
 #include <gps_extended_c.h>
@@ -65,6 +66,7 @@
 
  private:
     Gnss* mGnss = nullptr;
+    std::mutex mMutex;
     sp<IAGnssCallback> mAGnssCbIface = nullptr;
 };
 
diff --git a/gps/android/2.0/AGnssRil.cpp b/gps/android/2.0/AGnssRil.cpp
index d8005e4..84ea252 100644
--- a/gps/android/2.0/AGnssRil.cpp
+++ b/gps/android/2.0/AGnssRil.cpp
@@ -29,7 +29,7 @@
 #include <string>
 #include "Gnss.h"
 #include "AGnssRil.h"
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 
 typedef void* (getLocationInterface)();
 
diff --git a/gps/android/2.0/Android.mk b/gps/android/2.0/Android.mk
index e3422f9..1de5590 100644
--- a/gps/android/2.0/Android.mk
+++ b/gps/android/2.0/Android.mk
@@ -3,8 +3,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@2.0-impl-qti
 
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := \
@@ -72,8 +70,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@2.0-service-qti
 
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@2.0-service-qti.xml
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/gps/android/2.0/GnssMeasurement.cpp b/gps/android/2.0/GnssMeasurement.cpp
index 6cb55ca..3a93a3c 100644
--- a/gps/android/2.0/GnssMeasurement.cpp
+++ b/gps/android/2.0/GnssMeasurement.cpp
@@ -18,11 +18,15 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #define LOG_TAG "LocSvc_GnssMeasurementInterface"
 
 #include <log_util.h>
 #include "GnssMeasurement.h"
-#include "MeasurementAPIClient.h"
 
 namespace android {
 namespace hardware {
@@ -54,32 +58,41 @@
 // Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
 Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
         const sp<V1_0::IGnssMeasurementCallback>& callback)  {
+    return setCallback(callback, mGnssMeasurementCbIface, GNSS_POWER_MODE_INVALID);
+}
 
+template <typename T>
+Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+        const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode) {
     Return<GnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
+            IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
     if (mApi == nullptr) {
         LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
         return ret;
     }
+    if (myCallback != callback) {
+        if (nullptr == callback) {
+            LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+            mApi->measurementSetCallback(callback);
+            close();
+        } else {
+            if (nullptr != myCallback) {
+                myCallback->unlinkToDeath(mGnssMeasurementDeathRecipient);
+            }
+            myCallback = callback;
+            myCallback->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+            ret = mApi->measurementSetCallback(callback, powerMode);
+        }
+    }
 
-    clearInterfaces();
-
-    mGnssMeasurementCbIface = callback;
-    mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    return mApi->measurementSetCallback(callback);
+    return ret;
 }
 
 void GnssMeasurement::clearInterfaces() {
+    if (mApi != nullptr) {
+        mApi->measurementSetCallback<V1_0::IGnssMeasurementCallback>(nullptr);
+        mApi->measurementSetCallback<V1_1::IGnssMeasurementCallback>(nullptr);
+        mApi->measurementSetCallback<V2_0::IGnssMeasurementCallback>(nullptr);
     if (mGnssMeasurementCbIface != nullptr) {
         mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
         mGnssMeasurementCbIface = nullptr;
@@ -109,63 +122,15 @@
 // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
 Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
         const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) {
-
-    Return<GnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface_1_1 != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
-    if (nullptr == mApi) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return ret;
-    }
-
-    clearInterfaces();
-
-    mGnssMeasurementCbIface_1_1 = callback;
-    mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    GnssPowerMode powerMode = enableFullTracking?
-            GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
-
-    return mApi->measurementSetCallback_1_1(callback, powerMode);
+    return setCallback(callback, mGnssMeasurementCbIface_1_1,
+                       enableFullTracking ? GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2);
 }
 // Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
 Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
         const sp<V2_0::IGnssMeasurementCallback>& callback,
         bool enableFullTracking) {
-
-    Return<GnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface_2_0 != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
-    if (nullptr == mApi) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return ret;
-    }
-
-    clearInterfaces();
-
-    mGnssMeasurementCbIface_2_0 = callback;
-    mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    GnssPowerMode powerMode = enableFullTracking ?
-        GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
-
-    return mApi->measurementSetCallback_2_0(callback, powerMode);
+    return setCallback(callback, mGnssMeasurementCbIface_2_0,
+                       enableFullTracking ? GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2);
 }
 
 }  // namespace implementation
diff --git a/gps/android/2.0/GnssMeasurement.h b/gps/android/2.0/GnssMeasurement.h
index 7fa66b4..35c20d9 100644
--- a/gps/android/2.0/GnssMeasurement.h
+++ b/gps/android/2.0/GnssMeasurement.h
@@ -18,12 +18,18 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
 #define ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
 
 #include <android/hardware/gnss/2.0/IGnssMeasurement.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include "MeasurementAPIClient.h"
 
 namespace android {
 namespace hardware {
@@ -69,7 +75,9 @@
         sp<GnssMeasurement> mGnssMeasurement;
     };
 
- private:
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> setCallback(
+            const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode);
     sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
     sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
     sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
diff --git a/gps/android/2.0/location_api/MeasurementAPIClient.cpp b/gps/android/2.0/location_api/MeasurementAPIClient.cpp
index 425415f..e1cb3f8 100644
--- a/gps/android/2.0/location_api/MeasurementAPIClient.cpp
+++ b/gps/android/2.0/location_api/MeasurementAPIClient.cpp
@@ -82,52 +82,6 @@
     mGnssMeasurementCbIface_2_0 = nullptr;
 }
 
-// for GpsInterface
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
-{
-    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
-
-    mMutex.lock();
-    clearInterfaces();
-    mGnssMeasurementCbIface = callback;
-    mMutex.unlock();
-
-    return startTracking();
-}
-
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback_1_1(
-        const sp<V1_1::IGnssMeasurementCallback>& callback,
-        GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
-{
-    LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
-            __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
-
-    mMutex.lock();
-    clearInterfaces();
-    mGnssMeasurementCbIface_1_1 = callback;
-    mMutex.unlock();
-
-    return startTracking(powerMode, timeBetweenMeasurement);
-}
-
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback_2_0(
-    const sp<V2_0::IGnssMeasurementCallback>& callback,
-    GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
-{
-    LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
-        __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
-
-    mMutex.lock();
-    clearInterfaces();
-    mGnssMeasurementCbIface_2_0 = callback;
-    mMutex.unlock();
-
-    return startTracking(powerMode, timeBetweenMeasurement);
-}
-
 Return<IGnssMeasurement::GnssMeasurementStatus>
 MeasurementAPIClient::startTracking(
         GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
@@ -136,16 +90,6 @@
     memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
     locationCallbacks.size = sizeof(LocationCallbacks);
 
-    locationCallbacks.trackingCb = nullptr;
-    locationCallbacks.batchingCb = nullptr;
-    locationCallbacks.geofenceBreachCb = nullptr;
-    locationCallbacks.geofenceStatusCb = nullptr;
-    locationCallbacks.gnssLocationInfoCb = nullptr;
-    locationCallbacks.gnssNiCb = nullptr;
-    locationCallbacks.gnssSvCb = nullptr;
-    locationCallbacks.gnssNmeaCb = nullptr;
-
-    locationCallbacks.gnssMeasurementsCb = nullptr;
     if (mGnssMeasurementCbIface_2_0 != nullptr ||
         mGnssMeasurementCbIface_1_1 != nullptr ||
         mGnssMeasurementCbIface != nullptr) {
@@ -168,7 +112,7 @@
     }
 
     mTracking = true;
-    LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+    LOC_LOGd("(powermode: %d) (tbm %d)", (int)powerMode, timeBetweenMeasurement);
     locAPIStartTracking(options);
     return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
 }
@@ -177,6 +121,7 @@
 void MeasurementAPIClient::measurementClose() {
     LOC_LOGD("%s]: ()", __FUNCTION__);
     mTracking = false;
+    clearInterfaces();
     locAPIStopTracking();
 }
 
diff --git a/gps/android/2.0/location_api/MeasurementAPIClient.h b/gps/android/2.0/location_api/MeasurementAPIClient.h
index 6c2d38d..cd47c08 100644
--- a/gps/android/2.0/location_api/MeasurementAPIClient.h
+++ b/gps/android/2.0/location_api/MeasurementAPIClient.h
@@ -32,7 +32,6 @@
 
 #include <mutex>
 #include <android/hardware/gnss/2.0/IGnssMeasurement.h>
-//#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
 #include <LocationAPIClientBase.h>
 #include <hidl/Status.h>
 #include <gps_extended_c.h>
@@ -53,16 +52,15 @@
     MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
 
     // for GpsMeasurementInterface
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
-            const sp<V1_0::IGnssMeasurementCallback>& callback);
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
-            const sp<V1_1::IGnssMeasurementCallback>& callback,
-            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
-            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_0(
-            const sp<V2_0::IGnssMeasurementCallback>& callback,
-            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
-            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+            const sp<T>& callback, GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID) {
+        mMutex.lock();
+        setCallbackLocked(callback);
+        mMutex.unlock();
+
+        return startTracking(powerMode);
+    }
     void measurementClose();
     Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
             GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
@@ -72,6 +70,15 @@
     void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
 
 private:
+    inline void setCallbackLocked(const sp<V1_0::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface = callback;
+    }
+    inline void setCallbackLocked(const sp<V1_1::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface_1_1 = callback;
+    }
+    inline void setCallbackLocked(const sp<V2_0::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface_2_0 = callback;
+    }
     virtual ~MeasurementAPIClient();
 
     std::mutex mMutex;
diff --git a/gps/android/2.1/AGnss.cpp b/gps/android/2.1/AGnss.cpp
index ce7b3aa..33a8fc3 100644
--- a/gps/android/2.1/AGnss.cpp
+++ b/gps/android/2.1/AGnss.cpp
@@ -51,9 +51,6 @@
     V2_0::IAGnssCallback::AGnssType  aType;
     IAGnssCallback::AGnssStatusValue aStatus;
 
-    // cache the AGps Type
-    mType = type;
-
     switch (type) {
     case LOC_AGPS_TYPE_SUPL:
         aType = IAGnssCallback::AGnssType::SUPL;
@@ -87,8 +84,13 @@
         return;
     }
 
-    if (mAGnssCbIface != nullptr) {
-        auto r = mAGnssCbIface->agnssStatusCb(aType, aStatus);
+    mMutex.lock();
+    // cache the AGps Type
+    mType = type;
+    auto aGnssCbIface = mAGnssCbIface;
+    mMutex.unlock();
+    if (aGnssCbIface != nullptr) {
+        auto r = aGnssCbIface->agnssStatusCb(aType, aStatus);
         if (!r.isOk()) {
             LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
         }
@@ -106,7 +108,9 @@
     }
 
     // Save the interface
+    mMutex.lock();
     mAGnssCbIface = callback;
+    mMutex.unlock();
 
     AgpsCbInfo cbInfo = {};
     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
diff --git a/gps/android/2.1/AGnss.h b/gps/android/2.1/AGnss.h
index cf9c8a7..3d2cc7e 100644
--- a/gps/android/2.1/AGnss.h
+++ b/gps/android/2.1/AGnss.h
@@ -21,6 +21,7 @@
 #ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
 #define ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
 
+#include <mutex>
 #include <android/hardware/gnss/2.0/IAGnss.h>
 #include <hidl/Status.h>
 #include <gps_extended_c.h>
@@ -66,6 +67,7 @@
 
  private:
     Gnss* mGnss = nullptr;
+    std::mutex mMutex;
     sp<V2_0::IAGnssCallback> mAGnssCbIface = nullptr;
 
     AGpsExtType mType;
diff --git a/gps/android/2.1/AGnssRil.cpp b/gps/android/2.1/AGnssRil.cpp
index f413e93..49b98f6 100644
--- a/gps/android/2.1/AGnssRil.cpp
+++ b/gps/android/2.1/AGnssRil.cpp
@@ -29,7 +29,7 @@
 #include <string>
 #include "Gnss.h"
 #include "AGnssRil.h"
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 
 typedef void* (getLocationInterface)();
 
diff --git a/gps/android/2.1/Android.mk b/gps/android/2.1/Android.mk
index 4be97a9..0d1af7a 100644
--- a/gps/android/2.1/Android.mk
+++ b/gps/android/2.1/Android.mk
@@ -2,8 +2,6 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@2.1-impl-qti
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := \
@@ -74,8 +72,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := android.hardware.gnss@2.1-service-qti
 
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@2.1-service-qti.xml
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/gps/android/2.1/GnssMeasurement.cpp b/gps/android/2.1/GnssMeasurement.cpp
index af75802..de2ccd0 100644
--- a/gps/android/2.1/GnssMeasurement.cpp
+++ b/gps/android/2.1/GnssMeasurement.cpp
@@ -18,11 +18,15 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #define LOG_TAG "LocSvc_GnssMeasurementInterface"
 
 #include <log_util.h>
 #include "GnssMeasurement.h"
-#include "MeasurementAPIClient.h"
 
 namespace android {
 namespace hardware {
@@ -54,32 +58,44 @@
 // Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
 Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
         const sp<V1_0::IGnssMeasurementCallback>& callback)  {
+    return setCallback(callback, mGnssMeasurementCbIface, GNSS_POWER_MODE_INVALID);
+}
 
+template <typename T>
+Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+        const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode) {
     Return<GnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
+            IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
     if (mApi == nullptr) {
         LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
         return ret;
     }
 
-    clearInterfaces();
+    if (myCallback != callback) {
+        if (nullptr == callback) {
+            LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+            mApi->measurementSetCallback(callback);
+            close();
+        } else {
+            if (nullptr != myCallback) {
+                myCallback->unlinkToDeath(mGnssMeasurementDeathRecipient);
+            }
+            myCallback = callback;
+            myCallback->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+            ret = mApi->measurementSetCallback(callback, powerMode);
+        }
+    }
 
-    mGnssMeasurementCbIface = callback;
-    mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    return mApi->measurementSetCallback(callback);
+    return ret;
 }
 
 void GnssMeasurement::clearInterfaces() {
+    if (mApi != nullptr) {
+        mApi->measurementSetCallback<V1_0::IGnssMeasurementCallback>(nullptr);
+        mApi->measurementSetCallback<V1_1::IGnssMeasurementCallback>(nullptr);
+        mApi->measurementSetCallback<V2_0::IGnssMeasurementCallback>(nullptr);
+        mApi->measurementSetCallback<V2_1::IGnssMeasurementCallback>(nullptr);
+    }
     if (mGnssMeasurementCbIface != nullptr) {
         mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
         mGnssMeasurementCbIface = nullptr;
@@ -113,95 +129,24 @@
 // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
 Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
         const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) {
-
-    Return<GnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface_1_1 != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
-    if (nullptr == mApi) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return ret;
-    }
-
-    clearInterfaces();
-
-    mGnssMeasurementCbIface_1_1 = callback;
-    mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    GnssPowerMode powerMode = enableFullTracking?
-            GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
-
-    return mApi->measurementSetCallback_1_1(callback, powerMode);
+    return setCallback(callback, mGnssMeasurementCbIface_1_1,
+                       enableFullTracking ? GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2);
 }
+
 // Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
 Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
         const sp<V2_0::IGnssMeasurementCallback>& callback,
         bool enableFullTracking) {
-
-    Return<GnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface_2_0 != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
-    if (nullptr == mApi) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return ret;
-    }
-
-    clearInterfaces();
-
-    mGnssMeasurementCbIface_2_0 = callback;
-    mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    GnssPowerMode powerMode = enableFullTracking ?
-        GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
-
-    return mApi->measurementSetCallback_2_0(callback, powerMode);
+    return setCallback(callback, mGnssMeasurementCbIface_2_0,
+                       enableFullTracking ? GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2);
 }
 
 // Methods from ::android::hardware::gnss::V2_1::IGnssMeasurement follow.
 Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_1(
         const sp<::android::hardware::gnss::V2_1::IGnssMeasurementCallback>& callback,
         bool enableFullTracking) {
-    Return<GnssMeasurement::GnssMeasurementStatus> ret =
-        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
-    if (mGnssMeasurementCbIface_2_1 != nullptr) {
-        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
-        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
-    }
-
-    if (callback == nullptr) {
-        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
-        return ret;
-    }
-    if (nullptr == mApi) {
-        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
-        return ret;
-    }
-
-    clearInterfaces();
-
-    mGnssMeasurementCbIface_2_1 = callback;
-    mGnssMeasurementCbIface_2_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
-
-    GnssPowerMode powerMode = enableFullTracking ?
-            GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
-
-    return mApi->measurementSetCallback_2_1(callback, powerMode);
-
+    return setCallback(callback, mGnssMeasurementCbIface_2_1,
+                       enableFullTracking ? GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2);
 }
 
 }  // namespace implementation
diff --git a/gps/android/2.1/GnssMeasurement.h b/gps/android/2.1/GnssMeasurement.h
index 2ac45c6..96969e7 100644
--- a/gps/android/2.1/GnssMeasurement.h
+++ b/gps/android/2.1/GnssMeasurement.h
@@ -18,12 +18,18 @@
  * limitations under the License.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #ifndef ANDROID_HARDWARE_GNSS_V2_1_GNSSMEASUREMENT_H
 #define ANDROID_HARDWARE_GNSS_V2_1_GNSSMEASUREMENT_H
 
 #include <android/hardware/gnss/2.1/IGnssMeasurement.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include "MeasurementAPIClient.h"
 
 namespace android {
 namespace hardware {
@@ -74,7 +80,9 @@
         sp<GnssMeasurement> mGnssMeasurement;
     };
 
- private:
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> setCallback(
+            const sp<T>& callback, sp<T>& myCallback, GnssPowerMode powerMode);
     sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
     sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
     sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
diff --git a/gps/android/2.1/location_api/MeasurementAPIClient.cpp b/gps/android/2.1/location_api/MeasurementAPIClient.cpp
index 0028074..96a7a94 100644
--- a/gps/android/2.1/location_api/MeasurementAPIClient.cpp
+++ b/gps/android/2.1/location_api/MeasurementAPIClient.cpp
@@ -95,65 +95,6 @@
     mGnssMeasurementCbIface_2_1 = nullptr;
 }
 
-// for GpsInterface
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
-{
-    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
-
-    mMutex.lock();
-    clearInterfaces();
-    mGnssMeasurementCbIface = callback;
-    mMutex.unlock();
-
-    return startTracking();
-}
-
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback_1_1(
-        const sp<V1_1::IGnssMeasurementCallback>& callback,
-        GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
-{
-    LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
-            __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
-
-    mMutex.lock();
-    clearInterfaces();
-    mGnssMeasurementCbIface_1_1 = callback;
-    mMutex.unlock();
-
-    return startTracking(powerMode, timeBetweenMeasurement);
-}
-
-Return<IGnssMeasurement::GnssMeasurementStatus>
-MeasurementAPIClient::measurementSetCallback_2_0(
-    const sp<V2_0::IGnssMeasurementCallback>& callback,
-    GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
-{
-    LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
-        __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
-
-    mMutex.lock();
-    clearInterfaces();
-    mGnssMeasurementCbIface_2_0 = callback;
-    mMutex.unlock();
-
-    return startTracking(powerMode, timeBetweenMeasurement);
-}
-
-Return<IGnssMeasurement::GnssMeasurementStatus> MeasurementAPIClient::measurementSetCallback_2_1(
-        const sp<V2_1::IGnssMeasurementCallback>& callback,
-        GnssPowerMode powerMode, uint32_t timeBetweenMeasurement) {
-    LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
-        __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
-
-    mMutex.lock();
-    clearInterfaces();
-    mGnssMeasurementCbIface_2_1 = callback;
-    mMutex.unlock();
-
-    return startTracking(powerMode, timeBetweenMeasurement);
-}
 Return<IGnssMeasurement::GnssMeasurementStatus>
 MeasurementAPIClient::startTracking(
         GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
@@ -162,16 +103,6 @@
     memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
     locationCallbacks.size = sizeof(LocationCallbacks);
 
-    locationCallbacks.trackingCb = nullptr;
-    locationCallbacks.batchingCb = nullptr;
-    locationCallbacks.geofenceBreachCb = nullptr;
-    locationCallbacks.geofenceStatusCb = nullptr;
-    locationCallbacks.gnssLocationInfoCb = nullptr;
-    locationCallbacks.gnssNiCb = nullptr;
-    locationCallbacks.gnssSvCb = nullptr;
-    locationCallbacks.gnssNmeaCb = nullptr;
-
-    locationCallbacks.gnssMeasurementsCb = nullptr;
     if (mGnssMeasurementCbIface_2_1 != nullptr ||
         mGnssMeasurementCbIface_2_0 != nullptr ||
         mGnssMeasurementCbIface_1_1 != nullptr ||
@@ -195,7 +126,8 @@
     }
 
     mTracking = true;
-    LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+    LOC_LOGd("(powermode: %d) (tbm %d)", (int)powerMode, timeBetweenMeasurement);
+
     locAPIStartTracking(options);
     return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
 }
@@ -204,6 +136,7 @@
 void MeasurementAPIClient::measurementClose() {
     LOC_LOGD("%s]: ()", __FUNCTION__);
     mTracking = false;
+    clearInterfaces();
     locAPIStopTracking();
 }
 
diff --git a/gps/android/2.1/location_api/MeasurementAPIClient.h b/gps/android/2.1/location_api/MeasurementAPIClient.h
index 3e8805b..1a3051f 100644
--- a/gps/android/2.1/location_api/MeasurementAPIClient.h
+++ b/gps/android/2.1/location_api/MeasurementAPIClient.h
@@ -32,7 +32,6 @@
 
 #include <mutex>
 #include <android/hardware/gnss/2.1/IGnssMeasurement.h>
-//#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
 #include <android/hardware/gnss/2.1/IGnssMeasurementCallback.h>
 #include <LocationAPIClientBase.h>
 #include <hidl/Status.h>
@@ -54,20 +53,16 @@
     MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
 
     // for GpsMeasurementInterface
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
-            const sp<V1_0::IGnssMeasurementCallback>& callback);
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
-            const sp<V1_1::IGnssMeasurementCallback>& callback,
-            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
-            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_0(
-            const sp<V2_0::IGnssMeasurementCallback>& callback,
-            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
-            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
-    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_1(
-            const sp<V2_1::IGnssMeasurementCallback>& callback,
-            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
-            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+    template <typename T>
+    Return<IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+            const sp<T>& callback, GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID) {
+        mMutex.lock();
+        setCallbackLocked(callback);
+        mMutex.unlock();
+
+        return startTracking(powerMode);
+    }
+
     void measurementClose();
     Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
             GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
@@ -77,6 +72,18 @@
     void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
 
 private:
+    inline void setCallbackLocked(const sp<V1_0::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface = callback;
+    }
+    inline void setCallbackLocked(const sp<V1_1::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface_1_1 = callback;
+    }
+    inline void setCallbackLocked(const sp<V2_0::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface_2_0 = callback;
+    }
+    inline void setCallbackLocked(const sp<V2_1::IGnssMeasurementCallback>& callback) {
+        mGnssMeasurementCbIface_2_1 = callback;
+    }
     virtual ~MeasurementAPIClient();
 
     std::mutex mMutex;
diff --git a/gps/core/Android.bp b/gps/core/Android.bp
index fe9f067..bb6ef0c 100644
--- a/gps/core/Android.bp
+++ b/gps/core/Android.bp
@@ -22,6 +22,7 @@
         "LocContext.cpp",
         "loc_core_log.cpp",
         "data-items/DataItemsFactoryProxy.cpp",
+        "data-items/DataItemConcreteTypes.cpp",
         "SystemStatusOsObserver.cpp",
         "SystemStatus.cpp",
     ],
diff --git a/gps/core/Makefile.am b/gps/core/Makefile.am
index 291dbb5..42c878d 100644
--- a/gps/core/Makefile.am
+++ b/gps/core/Makefile.am
@@ -22,7 +22,8 @@
            EngineHubProxyBase.h \
            data-items/DataItemId.h \
            data-items/IDataItemCore.h \
-           data-items/DataItemConcreteTypesBase.h \
+           data-items/DataItemConcreteTypes.h \
+           data-items/DataItemsFactoryProxy.h \
            observer/IDataItemObserver.h \
            observer/IDataItemSubscription.h \
            observer/IFrameworkActionReq.h \
@@ -37,6 +38,7 @@
            LocContext.cpp \
            loc_core_log.cpp \
            data-items/DataItemsFactoryProxy.cpp \
+           data-items/DataItemConcreteTypes.cpp \
            SystemStatusOsObserver.cpp \
            SystemStatus.cpp
 
diff --git a/gps/core/SystemStatus.cpp b/gps/core/SystemStatus.cpp
index fe11de0..236d2b7 100644
--- a/gps/core/SystemStatus.cpp
+++ b/gps/core/SystemStatus.cpp
@@ -26,6 +26,43 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
+/*
+Changes from Qualcomm Innovation Center are provided under the following license:
+
+Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted (subject to the limitations in the
+disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #define LOG_TAG "LocSvc_SystemStatus"
 
 #include <inttypes.h>
@@ -40,7 +77,7 @@
 #include <DataItemsFactoryProxy.h>
 #include <SystemStatus.h>
 #include <SystemStatusOsObserver.h>
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 
 namespace loc_core
 {
@@ -748,18 +785,17 @@
 {
 }
 
-bool SystemStatusTimeAndClock::equals(const SystemStatusTimeAndClock& peer)
-{
-    if ((mGpsWeek != peer.mGpsWeek) ||
-        (mGpsTowMs != peer.mGpsTowMs) ||
-        (mTimeValid != peer.mTimeValid) ||
-        (mTimeSource != peer.mTimeSource) ||
-        (mTimeUnc != peer.mTimeUnc) ||
-        (mClockFreqBias != peer.mClockFreqBias) ||
-        (mClockFreqBiasUnc != peer.mClockFreqBiasUnc) ||
-        (mLeapSeconds != peer.mLeapSeconds) ||
-        (mLeapSecUnc != peer.mLeapSecUnc) ||
-        (mTimeUncNs != peer.mTimeUncNs)) {
+bool SystemStatusTimeAndClock::equals(const SystemStatusItemBase& peer) {
+    if ((mGpsWeek != ((const SystemStatusTimeAndClock&)peer).mGpsWeek) ||
+        (mGpsTowMs != ((const SystemStatusTimeAndClock&)peer).mGpsTowMs) ||
+        (mTimeValid != ((const SystemStatusTimeAndClock&)peer).mTimeValid) ||
+        (mTimeSource != ((const SystemStatusTimeAndClock&)peer).mTimeSource) ||
+        (mTimeUnc != ((const SystemStatusTimeAndClock&)peer).mTimeUnc) ||
+        (mClockFreqBias != ((const SystemStatusTimeAndClock&)peer).mClockFreqBias) ||
+        (mClockFreqBiasUnc != ((const SystemStatusTimeAndClock&)peer).mClockFreqBiasUnc) ||
+        (mLeapSeconds != ((const SystemStatusTimeAndClock&)peer).mLeapSeconds) ||
+        (mLeapSecUnc != ((const SystemStatusTimeAndClock&)peer).mLeapSecUnc) ||
+        (mTimeUncNs != ((const SystemStatusTimeAndClock&)peer).mTimeUncNs)) {
         return false;
     }
     return true;
@@ -790,9 +826,8 @@
 {
 }
 
-bool SystemStatusXoState::equals(const SystemStatusXoState& peer)
-{
-    if (mXoState != peer.mXoState) {
+bool SystemStatusXoState::equals(const SystemStatusItemBase& peer) {
+    if (mXoState != ((const SystemStatusXoState&)peer).mXoState) {
         return false;
     }
     return true;
@@ -832,27 +867,26 @@
 {
 }
 
-bool SystemStatusRfAndParams::equals(const SystemStatusRfAndParams& peer)
-{
-    if ((mPgaGain != peer.mPgaGain) ||
-        (mGpsBpAmpI != peer.mGpsBpAmpI) ||
-        (mGpsBpAmpQ != peer.mGpsBpAmpQ) ||
-        (mAdcI != peer.mAdcI) ||
-        (mAdcQ != peer.mAdcQ) ||
-        (mJammerGps != peer.mJammerGps) ||
-        (mJammerGlo != peer.mJammerGlo) ||
-        (mJammerBds != peer.mJammerBds) ||
-        (mJammerGal != peer.mJammerGal) ||
-        (mAgcGps != peer.mAgcGps) ||
-        (mAgcGlo != peer.mAgcGlo) ||
-        (mAgcBds != peer.mAgcBds) ||
-        (mAgcGal != peer.mAgcGal) ||
-        (mGloBpAmpI != peer.mGloBpAmpI) ||
-        (mGloBpAmpQ != peer.mGloBpAmpQ) ||
-        (mBdsBpAmpI != peer.mBdsBpAmpI) ||
-        (mBdsBpAmpQ != peer.mBdsBpAmpQ) ||
-        (mGalBpAmpI != peer.mGalBpAmpI) ||
-        (mGalBpAmpQ != peer.mGalBpAmpQ)) {
+bool SystemStatusRfAndParams::equals(const SystemStatusItemBase& peer) {
+    if ((mPgaGain != ((const SystemStatusRfAndParams&)peer).mPgaGain) ||
+        (mGpsBpAmpI != ((const SystemStatusRfAndParams&)peer).mGpsBpAmpI) ||
+        (mGpsBpAmpQ != ((const SystemStatusRfAndParams&)peer).mGpsBpAmpQ) ||
+        (mAdcI != ((const SystemStatusRfAndParams&)peer).mAdcI) ||
+        (mAdcQ != ((const SystemStatusRfAndParams&)peer).mAdcQ) ||
+        (mJammerGps != ((const SystemStatusRfAndParams&)peer).mJammerGps) ||
+        (mJammerGlo != ((const SystemStatusRfAndParams&)peer).mJammerGlo) ||
+        (mJammerBds != ((const SystemStatusRfAndParams&)peer).mJammerBds) ||
+        (mJammerGal != ((const SystemStatusRfAndParams&)peer).mJammerGal) ||
+        (mAgcGps != ((const SystemStatusRfAndParams&)peer).mAgcGps) ||
+        (mAgcGlo != ((const SystemStatusRfAndParams&)peer).mAgcGlo) ||
+        (mAgcBds != ((const SystemStatusRfAndParams&)peer).mAgcBds) ||
+        (mAgcGal != ((const SystemStatusRfAndParams&)peer).mAgcGal) ||
+        (mGloBpAmpI != ((const SystemStatusRfAndParams&)peer).mGloBpAmpI) ||
+        (mGloBpAmpQ != ((const SystemStatusRfAndParams&)peer).mGloBpAmpQ) ||
+        (mBdsBpAmpI != ((const SystemStatusRfAndParams&)peer).mBdsBpAmpI) ||
+        (mBdsBpAmpQ != ((const SystemStatusRfAndParams&)peer).mBdsBpAmpQ) ||
+        (mGalBpAmpI != ((const SystemStatusRfAndParams&)peer).mGalBpAmpI) ||
+        (mGalBpAmpQ != ((const SystemStatusRfAndParams&)peer).mGalBpAmpQ)) {
         return false;
     }
     return true;
@@ -888,9 +922,8 @@
 {
 }
 
-bool SystemStatusErrRecovery::equals(const SystemStatusErrRecovery& peer)
-{
-    if (mRecErrorRecovery != peer.mRecErrorRecovery) {
+bool SystemStatusErrRecovery::equals(const SystemStatusItemBase& peer) {
+    if (mRecErrorRecovery != ((const SystemStatusErrRecovery&)peer).mRecErrorRecovery) {
         return false;
     }
     return true;
@@ -918,15 +951,14 @@
 {
 }
 
-bool SystemStatusInjectedPosition::equals(const SystemStatusInjectedPosition& peer)
-{
-    if ((mEpiValidity != peer.mEpiValidity) ||
-        (mEpiLat != peer.mEpiLat) ||
-        (mEpiLon != peer.mEpiLon) ||
-        (mEpiAlt != peer.mEpiAlt) ||
-        (mEpiHepe != peer.mEpiHepe) ||
-        (mEpiAltUnc != peer.mEpiAltUnc) ||
-        (mEpiSrc != peer.mEpiSrc)) {
+bool SystemStatusInjectedPosition::equals(const SystemStatusItemBase& peer) {
+    if ((mEpiValidity != ((const SystemStatusInjectedPosition&)peer).mEpiValidity) ||
+        (mEpiLat != ((const SystemStatusInjectedPosition&)peer).mEpiLat) ||
+        (mEpiLon != ((const SystemStatusInjectedPosition&)peer).mEpiLon) ||
+        (mEpiAlt != ((const SystemStatusInjectedPosition&)peer).mEpiAlt) ||
+        (mEpiHepe != ((const SystemStatusInjectedPosition&)peer).mEpiHepe) ||
+        (mEpiAltUnc != ((const SystemStatusInjectedPosition&)peer).mEpiAltUnc) ||
+        (mEpiSrc != ((const SystemStatusInjectedPosition&)peer).mEpiSrc)) {
         return false;
     }
     return true;
@@ -959,13 +991,12 @@
 {
 }
 
-bool SystemStatusBestPosition::equals(const SystemStatusBestPosition& peer)
-{
-    if ((mBestLat != peer.mBestLat) ||
-        (mBestLon != peer.mBestLon) ||
-        (mBestAlt != peer.mBestAlt) ||
-        (mBestHepe != peer.mBestHepe) ||
-        (mBestAltUnc != peer.mBestAltUnc)) {
+bool SystemStatusBestPosition::equals(const SystemStatusItemBase& peer) {
+    if ((mBestLat != ((const SystemStatusBestPosition&)peer).mBestLat) ||
+        (mBestLon != ((const SystemStatusBestPosition&)peer).mBestLon) ||
+        (mBestAlt != ((const SystemStatusBestPosition&)peer).mBestAlt) ||
+        (mBestHepe != ((const SystemStatusBestPosition&)peer).mBestHepe) ||
+        (mBestAltUnc != ((const SystemStatusBestPosition&)peer).mBestAltUnc)) {
         return false;
     }
     return true;
@@ -1003,21 +1034,20 @@
 {
 }
 
-bool SystemStatusXtra::equals(const SystemStatusXtra& peer)
-{
-    if ((mXtraValidMask != peer.mXtraValidMask) ||
-        (mGpsXtraAge != peer.mGpsXtraAge) ||
-        (mGloXtraAge != peer.mGloXtraAge) ||
-        (mBdsXtraAge != peer.mBdsXtraAge) ||
-        (mGalXtraAge != peer.mGalXtraAge) ||
-        (mQzssXtraAge != peer.mQzssXtraAge) ||
-        (mNavicXtraAge != peer.mNavicXtraAge) ||
-        (mGpsXtraValid != peer.mGpsXtraValid) ||
-        (mGloXtraValid != peer.mGloXtraValid) ||
-        (mBdsXtraValid != peer.mBdsXtraValid) ||
-        (mGalXtraValid != peer.mGalXtraValid) ||
-        (mQzssXtraValid != peer.mQzssXtraValid) ||
-        (mNavicXtraValid != peer.mNavicXtraValid)) {
+bool SystemStatusXtra::equals(const SystemStatusItemBase& peer) {
+    if ((mXtraValidMask != ((const SystemStatusXtra&)peer).mXtraValidMask) ||
+        (mGpsXtraAge != ((const SystemStatusXtra&)peer).mGpsXtraAge) ||
+        (mGloXtraAge != ((const SystemStatusXtra&)peer).mGloXtraAge) ||
+        (mBdsXtraAge != ((const SystemStatusXtra&)peer).mBdsXtraAge) ||
+        (mGalXtraAge != ((const SystemStatusXtra&)peer).mGalXtraAge) ||
+        (mQzssXtraAge != ((const SystemStatusXtra&)peer).mQzssXtraAge) ||
+        (mNavicXtraAge != ((const SystemStatusXtra&)peer).mNavicXtraAge) ||
+        (mGpsXtraValid != ((const SystemStatusXtra&)peer).mGpsXtraValid) ||
+        (mGloXtraValid != ((const SystemStatusXtra&)peer).mGloXtraValid) ||
+        (mBdsXtraValid != ((const SystemStatusXtra&)peer).mBdsXtraValid) ||
+        (mGalXtraValid != ((const SystemStatusXtra&)peer).mGalXtraValid) ||
+        (mQzssXtraValid != ((const SystemStatusXtra&)peer).mQzssXtraValid) ||
+        (mNavicXtraValid != ((const SystemStatusXtra&)peer).mNavicXtraValid)) {
         return false;
     }
     return true;
@@ -1053,13 +1083,12 @@
 {
 }
 
-bool SystemStatusEphemeris::equals(const SystemStatusEphemeris& peer)
-{
-    if ((mGpsEpheValid != peer.mGpsEpheValid) ||
-        (mGloEpheValid != peer.mGloEpheValid) ||
-        (mBdsEpheValid != peer.mBdsEpheValid) ||
-        (mGalEpheValid != peer.mGalEpheValid) ||
-        (mQzssEpheValid != peer.mQzssEpheValid)) {
+bool SystemStatusEphemeris::equals(const SystemStatusItemBase& peer) {
+    if ((mGpsEpheValid != ((const SystemStatusEphemeris&)peer).mGpsEpheValid) ||
+        (mGloEpheValid != ((const SystemStatusEphemeris&)peer).mGloEpheValid) ||
+        (mBdsEpheValid != ((const SystemStatusEphemeris&)peer).mBdsEpheValid) ||
+        (mGalEpheValid != ((const SystemStatusEphemeris&)peer).mGalEpheValid) ||
+        (mQzssEpheValid != ((const SystemStatusEphemeris&)peer).mQzssEpheValid)) {
         return false;
     }
     return true;
@@ -1102,23 +1131,22 @@
 {
 }
 
-bool SystemStatusSvHealth::equals(const SystemStatusSvHealth& peer)
-{
-    if ((mGpsUnknownMask != peer.mGpsUnknownMask) ||
-        (mGloUnknownMask != peer.mGloUnknownMask) ||
-        (mBdsUnknownMask != peer.mBdsUnknownMask) ||
-        (mGalUnknownMask != peer.mGalUnknownMask) ||
-        (mQzssUnknownMask != peer.mQzssUnknownMask) ||
-        (mGpsGoodMask != peer.mGpsGoodMask) ||
-        (mGloGoodMask != peer.mGloGoodMask) ||
-        (mBdsGoodMask != peer.mBdsGoodMask) ||
-        (mGalGoodMask != peer.mGalGoodMask) ||
-        (mQzssGoodMask != peer.mQzssGoodMask) ||
-        (mGpsBadMask != peer.mGpsBadMask) ||
-        (mGloBadMask != peer.mGloBadMask) ||
-        (mBdsBadMask != peer.mBdsBadMask) ||
-        (mGalBadMask != peer.mGalBadMask) ||
-        (mQzssBadMask != peer.mQzssBadMask)) {
+bool SystemStatusSvHealth::equals(const SystemStatusItemBase& peer) {
+    if ((mGpsUnknownMask != ((const SystemStatusSvHealth&)peer).mGpsUnknownMask) ||
+        (mGloUnknownMask != ((const SystemStatusSvHealth&)peer).mGloUnknownMask) ||
+        (mBdsUnknownMask != ((const SystemStatusSvHealth&)peer).mBdsUnknownMask) ||
+        (mGalUnknownMask != ((const SystemStatusSvHealth&)peer).mGalUnknownMask) ||
+        (mQzssUnknownMask != ((const SystemStatusSvHealth&)peer).mQzssUnknownMask) ||
+        (mGpsGoodMask != ((const SystemStatusSvHealth&)peer).mGpsGoodMask) ||
+        (mGloGoodMask != ((const SystemStatusSvHealth&)peer).mGloGoodMask) ||
+        (mBdsGoodMask != ((const SystemStatusSvHealth&)peer).mBdsGoodMask) ||
+        (mGalGoodMask != ((const SystemStatusSvHealth&)peer).mGalGoodMask) ||
+        (mQzssGoodMask != ((const SystemStatusSvHealth&)peer).mQzssGoodMask) ||
+        (mGpsBadMask != ((const SystemStatusSvHealth&)peer).mGpsBadMask) ||
+        (mGloBadMask != ((const SystemStatusSvHealth&)peer).mGloBadMask) ||
+        (mBdsBadMask != ((const SystemStatusSvHealth&)peer).mBdsBadMask) ||
+        (mGalBadMask != ((const SystemStatusSvHealth&)peer).mGalBadMask) ||
+        (mQzssBadMask != ((const SystemStatusSvHealth&)peer).mQzssBadMask)) {
         return false;
     }
     return true;
@@ -1157,9 +1185,8 @@
 {
 }
 
-bool SystemStatusPdr::equals(const SystemStatusPdr& peer)
-{
-    if (mFixInfoMask != peer.mFixInfoMask) {
+bool SystemStatusPdr::equals(const SystemStatusItemBase& peer) {
+    if (mFixInfoMask != ((const SystemStatusPdr&)peer).mFixInfoMask) {
         return false;
     }
     return true;
@@ -1183,12 +1210,11 @@
     }
 }
 
-bool SystemStatusNavData::equals(const SystemStatusNavData& peer)
-{
+bool SystemStatusNavData::equals(const SystemStatusItemBase& peer) {
     for (uint32_t i=0; i<SV_ALL_NUM; i++) {
-        if ((mNav[i].mType != peer.mNav[i].mType) ||
-            (mNav[i].mSource != peer.mNav[i].mSource) ||
-            (mNav[i].mAgeSec != peer.mNav[i].mAgeSec)) {
+        if ((mNav[i].mType != ((const SystemStatusNavData&)peer).mNav[i].mType) ||
+            (mNav[i].mSource != ((const SystemStatusNavData&)peer).mNav[i].mSource) ||
+            (mNav[i].mAgeSec != ((const SystemStatusNavData&)peer).mNav[i].mAgeSec)) {
             return false;
         }
     }
@@ -1215,10 +1241,9 @@
 {
 }
 
-bool SystemStatusPositionFailure::equals(const SystemStatusPositionFailure& peer)
-{
-    if ((mFixInfoMask != peer.mFixInfoMask) ||
-        (mHepeLimit != peer.mHepeLimit)) {
+bool SystemStatusPositionFailure::equals(const SystemStatusItemBase& peer) {
+    if ((mFixInfoMask != ((const SystemStatusPositionFailure&)peer).mFixInfoMask) ||
+        (mHepeLimit != ((const SystemStatusPositionFailure&)peer).mHepeLimit)) {
         return false;
     }
     return true;
@@ -1236,11 +1261,13 @@
 /******************************************************************************
  SystemStatusLocation
 ******************************************************************************/
-bool SystemStatusLocation::equals(const SystemStatusLocation& peer)
-{
-    if ((mLocation.gpsLocation.latitude != peer.mLocation.gpsLocation.latitude) ||
-        (mLocation.gpsLocation.longitude != peer.mLocation.gpsLocation.longitude) ||
-        (mLocation.gpsLocation.altitude != peer.mLocation.gpsLocation.altitude)) {
+bool SystemStatusLocation::equals(const SystemStatusItemBase& peer) {
+    if ((mLocation.gpsLocation.latitude !=
+                ((const SystemStatusLocation&)peer).mLocation.gpsLocation.latitude) ||
+        (mLocation.gpsLocation.longitude !=
+                ((const SystemStatusLocation&)peer).mLocation.gpsLocation.longitude) ||
+        (mLocation.gpsLocation.altitude !=
+                ((const SystemStatusLocation&)peer).mLocation.gpsLocation.altitude)) {
         return false;
     }
     return true;
@@ -1290,8 +1317,10 @@
 void SystemStatus::resetNetworkInfo() {
     for (int i=0; i<mCache.mNetworkInfo.size(); ++i) {
         // Reset all the cached NetworkInfo Items as disconnected
-        eventConnectionStatus(false, mCache.mNetworkInfo[i].mType, mCache.mNetworkInfo[i].mRoaming,
-                mCache.mNetworkInfo[i].mNetworkHandle, mCache.mNetworkInfo[i].mApn);
+        eventConnectionStatus(false, mCache.mNetworkInfo[i].mDataItem.mType,
+                mCache.mNetworkInfo[i].mDataItem.mRoaming,
+                mCache.mNetworkInfo[i].mDataItem.mNetworkHandle,
+                mCache.mNetworkInfo[i].mDataItem.mApn);
     }
 }
 
@@ -1496,91 +1525,99 @@
     {
         case AIRPLANEMODE_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mAirplaneMode,
-                    SystemStatusAirplaneMode(*(static_cast<AirplaneModeDataItemBase*>(dataitem))));
+                    SystemStatusAirplaneMode(*(static_cast<AirplaneModeDataItem*>(dataitem))));
             break;
         case ENH_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mENH,
-                    SystemStatusENH(*(static_cast<ENHDataItemBase*>(dataitem))));
+                    SystemStatusENH(*(static_cast<ENHDataItem*>(dataitem))));
             break;
         case GPSSTATE_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mGPSState,
-                    SystemStatusGpsState(*(static_cast<GPSStateDataItemBase*>(dataitem))));
+                    SystemStatusGpsState(*(static_cast<GPSStateDataItem*>(dataitem))));
             break;
         case NLPSTATUS_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mNLPStatus,
-                    SystemStatusNLPStatus(*(static_cast<NLPStatusDataItemBase*>(dataitem))));
+                    SystemStatusNLPStatus(*(static_cast<NLPStatusDataItem*>(dataitem))));
             break;
         case WIFIHARDWARESTATE_DATA_ITEM_ID:
-            ret = setIteminReport(mCache.mWifiHardwareState,
-                    SystemStatusWifiHardwareState(*(static_cast<WifiHardwareStateDataItemBase*>(dataitem))));
+            ret = setIteminReport(mCache.mWifiHardwareState, SystemStatusWifiHardwareState(
+                        *(static_cast<WifiHardwareStateDataItem*>(dataitem))));
             break;
         case NETWORKINFO_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mNetworkInfo,
-                    SystemStatusNetworkInfo(*(static_cast<NetworkInfoDataItemBase*>(dataitem))));
+                    SystemStatusNetworkInfo(*(static_cast<NetworkInfoDataItem*>(dataitem))));
+            // Update latest mAllTypes/mAllNetworkHandles of original obj to notify clients
+            if (ret) {
+                (static_cast<NetworkInfoDataItem*>(dataitem))->mAllTypes =
+                        mCache.mNetworkInfo.back().mDataItem.mAllTypes;
+                memcpy((static_cast<NetworkInfoDataItem*>(dataitem))->mAllNetworkHandles,
+                        mCache.mNetworkInfo.back().mDataItem.mAllNetworkHandles, sizeof((
+                        static_cast<NetworkInfoDataItem*>(dataitem))->mAllNetworkHandles));
+            }
             break;
         case RILSERVICEINFO_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mRilServiceInfo,
-                    SystemStatusServiceInfo(*(static_cast<RilServiceInfoDataItemBase*>(dataitem))));
+                    SystemStatusServiceInfo(*(static_cast<RilServiceInfoDataItem*>(dataitem))));
             break;
         case RILCELLINFO_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mRilCellInfo,
-                    SystemStatusRilCellInfo(*(static_cast<RilCellInfoDataItemBase*>(dataitem))));
+                    SystemStatusRilCellInfo(*(static_cast<RilCellInfoDataItem*>(dataitem))));
             break;
         case SERVICESTATUS_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mServiceStatus,
-                    SystemStatusServiceStatus(*(static_cast<ServiceStatusDataItemBase*>(dataitem))));
+                    SystemStatusServiceStatus(*(static_cast<ServiceStatusDataItem*>(dataitem))));
             break;
         case MODEL_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mModel,
-                    SystemStatusModel(*(static_cast<ModelDataItemBase*>(dataitem))));
+                    SystemStatusModel(*(static_cast<ModelDataItem*>(dataitem))));
             break;
         case MANUFACTURER_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mManufacturer,
-                    SystemStatusManufacturer(*(static_cast<ManufacturerDataItemBase*>(dataitem))));
+                    SystemStatusManufacturer(*(static_cast<ManufacturerDataItem*>(dataitem))));
             break;
         case ASSISTED_GPS_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mAssistedGps,
-                    SystemStatusAssistedGps(*(static_cast<AssistedGpsDataItemBase*>(dataitem))));
+                    SystemStatusAssistedGps(*(static_cast<AssistedGpsDataItem*>(dataitem))));
             break;
         case SCREEN_STATE_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mScreenState,
-                    SystemStatusScreenState(*(static_cast<ScreenStateDataItemBase*>(dataitem))));
+                    SystemStatusScreenState(*(static_cast<ScreenStateDataItem*>(dataitem))));
             break;
         case POWER_CONNECTED_STATE_DATA_ITEM_ID:
-            ret = setIteminReport(mCache.mPowerConnectState,
-                    SystemStatusPowerConnectState(*(static_cast<PowerConnectStateDataItemBase*>(dataitem))));
+            ret = setIteminReport(mCache.mPowerConnectState, SystemStatusPowerConnectState(
+                        *(static_cast<PowerConnectStateDataItem*>(dataitem))));
             break;
         case TIMEZONE_CHANGE_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mTimeZoneChange,
-                    SystemStatusTimeZoneChange(*(static_cast<TimeZoneChangeDataItemBase*>(dataitem))));
+                    SystemStatusTimeZoneChange(*(static_cast<TimeZoneChangeDataItem*>(dataitem))));
             break;
         case TIME_CHANGE_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mTimeChange,
-                    SystemStatusTimeChange(*(static_cast<TimeChangeDataItemBase*>(dataitem))));
+                    SystemStatusTimeChange(*(static_cast<TimeChangeDataItem*>(dataitem))));
             break;
         case WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID:
-            ret = setIteminReport(mCache.mWifiSupplicantStatus,
-                    SystemStatusWifiSupplicantStatus(*(static_cast<WifiSupplicantStatusDataItemBase*>(dataitem))));
+            ret = setIteminReport(mCache.mWifiSupplicantStatus, SystemStatusWifiSupplicantStatus(
+                        *(static_cast<WifiSupplicantStatusDataItem*>(dataitem))));
             break;
         case SHUTDOWN_STATE_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mShutdownState,
-                    SystemStatusShutdownState(*(static_cast<ShutdownStateDataItemBase*>(dataitem))));
+                    SystemStatusShutdownState(*(static_cast<ShutdownStateDataItem*>(dataitem))));
             break;
         case TAC_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mTac,
-                    SystemStatusTac(*(static_cast<TacDataItemBase*>(dataitem))));
+                    SystemStatusTac(*(static_cast<TacDataItem*>(dataitem))));
             break;
         case MCCMNC_DATA_ITEM_ID:
             ret = setIteminReport(mCache.mMccMnc,
-                    SystemStatusMccMnc(*(static_cast<MccmncDataItemBase*>(dataitem))));
+                    SystemStatusMccMnc(*(static_cast<MccmncDataItem*>(dataitem))));
             break;
         case BTLE_SCAN_DATA_ITEM_ID:
-            ret = setIteminReport(mCache.mBtDeviceScanDetail,
-                    SystemStatusBtDeviceScanDetail(*(static_cast<BtDeviceScanDetailsDataItemBase*>(dataitem))));
+            ret = setIteminReport(mCache.mBtDeviceScanDetail, SystemStatusBtDeviceScanDetail(
+                        *(static_cast<BtDeviceScanDetailsDataItem*>(dataitem))));
             break;
         case BT_SCAN_DATA_ITEM_ID:
-            ret = setIteminReport(mCache.mBtLeDeviceScanDetail,
-                    SystemStatusBtleDeviceScanDetail(*(static_cast<BtLeDeviceScanDetailsDataItemBase*>(dataitem))));
+            ret = setIteminReport(mCache.mBtLeDeviceScanDetail, SystemStatusBtleDeviceScanDetail(
+                        *(static_cast<BtLeDeviceScanDetailsDataItem*>(dataitem))));
             break;
         default:
             break;
@@ -1739,7 +1776,7 @@
     // send networkinof dataitem to systemstatus observer clients
     SystemStatusNetworkInfo s(type, "", "", connected, roaming,
                               (uint64_t) networkHandle, apn);
-    mSysStatusObsvr.notify({&s});
+    mSysStatusObsvr.notify({&s.mDataItem});
 
     return true;
 }
@@ -1754,7 +1791,35 @@
 bool SystemStatus::updatePowerConnectState(bool charging)
 {
     SystemStatusPowerConnectState s(charging);
-    mSysStatusObsvr.notify({&s});
+    mSysStatusObsvr.notify({&s.mDataItem});
+    return true;
+}
+
+/******************************************************************************
+@brief      API to update ENH
+
+@param[In]  user consent
+
+@return     true when successfully done
+******************************************************************************/
+bool SystemStatus::eventOptInStatus(bool userConsent)
+{
+    SystemStatusENH s(userConsent, ENHDataItem::FIELD_CONSENT);
+    mSysStatusObsvr.notify({&s.mDataItem});
+    return true;
+}
+
+/******************************************************************************
+@brief      API to update Region
+
+@param[In]  region
+
+@return     true when successfully done
+******************************************************************************/
+bool SystemStatus::eventRegionStatus(bool region)
+{
+    SystemStatusENH s(region, ENHDataItem::FIELD_REGION);
+    mSysStatusObsvr.notify({&s.mDataItem});
     return true;
 }
 } // namespace loc_core
diff --git a/gps/core/SystemStatus.h b/gps/core/SystemStatus.h
index 638933a..6e14156 100644
--- a/gps/core/SystemStatus.h
+++ b/gps/core/SystemStatus.h
@@ -26,6 +26,43 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
+/*
+Changes from Qualcomm Innovation Center are provided under the following license:
+
+Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted (subject to the limitations in the
+disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 __SYSTEM_STATUS__
 #define __SYSTEM_STATUS__
 
@@ -39,7 +76,7 @@
 #include <MsgTask.h>
 #include <IDataItemCore.h>
 #include <IOsObserver.h>
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 #include <SystemStatusOsObserver.h>
 
 #include <gps_extended_c.h>
@@ -88,6 +125,7 @@
     }
     virtual void dump(void) {};
     inline virtual bool ignore() { return false; };
+    virtual bool equals(const SystemStatusItemBase& peer) { return false; }
 };
 
 class SystemStatusLocation : public SystemStatusItemBase
@@ -103,7 +141,7 @@
         mValid(true),
         mLocation(location),
         mLocationEx(locationEx) {}
-    bool equals(const SystemStatusLocation& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -133,7 +171,7 @@
         mLeapSecUnc(0),
         mTimeUncNs(0ULL) {}
     inline SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea);
-    bool equals(const SystemStatusTimeAndClock& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -144,7 +182,7 @@
     inline SystemStatusXoState() :
         mXoState(0) {}
     inline SystemStatusXoState(const SystemStatusPQWM1& nmea);
-    bool equals(const SystemStatusXoState& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -191,7 +229,7 @@
         mGalBpAmpI(0),
         mGalBpAmpQ(0) {}
     inline SystemStatusRfAndParams(const SystemStatusPQWM1& nmea);
-    bool equals(const SystemStatusRfAndParams& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -202,7 +240,7 @@
     inline SystemStatusErrRecovery() :
         mRecErrorRecovery(0) {};
     inline SystemStatusErrRecovery(const SystemStatusPQWM1& nmea);
-    bool equals(const SystemStatusErrRecovery& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     inline bool ignore() override { return 0 == mRecErrorRecovery; };
     void dump(void) override;
 };
@@ -227,7 +265,7 @@
         mEpiAltUnc(0),
         mEpiSrc(0) {}
     inline SystemStatusInjectedPosition(const SystemStatusPQWP1& nmea);
-    bool equals(const SystemStatusInjectedPosition& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -249,7 +287,7 @@
         mBestHepe(0),
         mBestAltUnc(0) {}
     inline SystemStatusBestPosition(const SystemStatusPQWP2& nmea);
-    bool equals(const SystemStatusBestPosition& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -285,7 +323,7 @@
         mQzssXtraValid(0),
         mNavicXtraValid(0) {}
     inline SystemStatusXtra(const SystemStatusPQWP3& nmea);
-    bool equals(const SystemStatusXtra& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -305,7 +343,7 @@
         mGalEpheValid(0ULL),
         mQzssEpheValid(0) {}
     inline SystemStatusEphemeris(const SystemStatusPQWP4& nmea);
-    bool equals(const SystemStatusEphemeris& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -351,7 +389,7 @@
         mQzssBadMask(0),
         mNavicBadMask(0) {}
     inline SystemStatusSvHealth(const SystemStatusPQWP5& nmea);
-    bool equals(const SystemStatusSvHealth& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -363,7 +401,7 @@
     inline SystemStatusPdr() :
         mFixInfoMask(0) {}
     inline SystemStatusPdr(const SystemStatusPQWP6& nmea);
-    bool equals(const SystemStatusPdr& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -387,7 +425,7 @@
         }
     }
     inline SystemStatusNavData(const SystemStatusPQWP7& nmea);
-    bool equals(const SystemStatusNavData& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
@@ -401,153 +439,139 @@
         mFixInfoMask(0),
         mHepeLimit(0) {}
     inline SystemStatusPositionFailure(const SystemStatusPQWS1& nmea);
-    bool equals(const SystemStatusPositionFailure& peer);
+    bool equals(const SystemStatusItemBase& peer) override;
     void dump(void) override;
 };
 
 /******************************************************************************
  SystemStatus report data structure - from DataItem observer
 ******************************************************************************/
-class SystemStatusAirplaneMode : public SystemStatusItemBase,
-        public AirplaneModeDataItemBase
-{
+class SystemStatusAirplaneMode : public SystemStatusItemBase {
 public:
-    inline SystemStatusAirplaneMode(bool mode=false) :
-            AirplaneModeDataItemBase(mode) {}
-    inline SystemStatusAirplaneMode(const AirplaneModeDataItemBase& itemBase) :
-            AirplaneModeDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusAirplaneMode& peer) {
-        return (mMode == peer.mMode);
+    AirplaneModeDataItem mDataItem;
+    inline SystemStatusAirplaneMode(bool mode=false): mDataItem(mode) {}
+    inline SystemStatusAirplaneMode(const AirplaneModeDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mMode == ((const SystemStatusAirplaneMode&)peer).mDataItem.mMode;
     }
 };
 
-class SystemStatusENH : public SystemStatusItemBase,
-        public ENHDataItemBase
-{
+class SystemStatusENH : public SystemStatusItemBase {
 public:
-    inline SystemStatusENH(bool enabled=false) :
-            ENHDataItemBase(enabled) {}
-    inline SystemStatusENH(const ENHDataItemBase& itemBase) :
-            ENHDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusENH& peer) {
-        return (mEnabled == peer.mEnabled);
+    ENHDataItem mDataItem;
+    inline SystemStatusENH(bool enabled, ENHDataItem::Fields updateBit = ENHDataItem::FIELD_MAX):
+            mDataItem(enabled, updateBit) {}
+    inline SystemStatusENH(const ENHDataItem& itemBase): mDataItem(itemBase) {}
+    inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& peer) {
+        mDataItem.mEnhFields = ((const SystemStatusENH&)peer).mDataItem.mEnhFields;
+        mDataItem.updateFields();
+        return *this;
+    }
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mEnhFields == ((const SystemStatusENH&)peer).mDataItem.mEnhFields;
     }
 };
 
-class SystemStatusGpsState : public SystemStatusItemBase,
-        public GPSStateDataItemBase
-{
+class SystemStatusGpsState : public SystemStatusItemBase {
 public:
-    inline SystemStatusGpsState(bool enabled=false) :
-            GPSStateDataItemBase(enabled) {}
-    inline SystemStatusGpsState(const GPSStateDataItemBase& itemBase) :
-            GPSStateDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusGpsState& peer) {
-        return (mEnabled == peer.mEnabled);
+    GPSStateDataItem mDataItem;
+    inline SystemStatusGpsState(bool enabled=false): mDataItem(enabled) {}
+    inline SystemStatusGpsState(const GPSStateDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mEnabled == ((const SystemStatusGpsState&)peer).mDataItem.mEnabled;
     }
     inline void dump(void) override {
-        LOC_LOGD("GpsState: state=%u", mEnabled);
+        LOC_LOGD("GpsState: state=%u", mDataItem.mEnabled);
     }
 };
 
-class SystemStatusNLPStatus : public SystemStatusItemBase,
-        public NLPStatusDataItemBase
-{
+class SystemStatusNLPStatus : public SystemStatusItemBase {
 public:
-    inline SystemStatusNLPStatus(bool enabled=false) :
-            NLPStatusDataItemBase(enabled) {}
-    inline SystemStatusNLPStatus(const NLPStatusDataItemBase& itemBase) :
-            NLPStatusDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusNLPStatus& peer) {
-        return (mEnabled == peer.mEnabled);
+    NLPStatusDataItem mDataItem;
+    inline SystemStatusNLPStatus(bool enabled=false): mDataItem(enabled) {}
+    inline SystemStatusNLPStatus(const NLPStatusDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mEnabled == ((const SystemStatusNLPStatus&)peer).mDataItem.mEnabled;
     }
 };
 
-class SystemStatusWifiHardwareState : public SystemStatusItemBase,
-        public WifiHardwareStateDataItemBase
-{
+class SystemStatusWifiHardwareState : public SystemStatusItemBase {
 public:
-    inline SystemStatusWifiHardwareState(bool enabled=false) :
-            WifiHardwareStateDataItemBase(enabled) {}
-    inline SystemStatusWifiHardwareState(const WifiHardwareStateDataItemBase& itemBase) :
-            WifiHardwareStateDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusWifiHardwareState& peer) {
-        return (mEnabled == peer.mEnabled);
+    WifiHardwareStateDataItem mDataItem;
+    inline SystemStatusWifiHardwareState(bool enabled=false): mDataItem(enabled) {}
+    inline SystemStatusWifiHardwareState(const WifiHardwareStateDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mEnabled == ((const SystemStatusWifiHardwareState&)peer).mDataItem.mEnabled;
     }
 };
 
-class SystemStatusNetworkInfo : public SystemStatusItemBase,
-        public NetworkInfoDataItemBase
-{
-    NetworkInfoDataItemBase* mSrcObjPtr;
+class SystemStatusNetworkInfo : public SystemStatusItemBase {
 public:
-    inline SystemStatusNetworkInfo(
-            int32_t type = 0,
-            std::string typeName = "",
-            string subTypeName = "",
-            bool connected = false,
-            bool roaming = false,
-            uint64_t networkHandle = NETWORK_HANDLE_UNKNOWN,
-            string apn = "") :
-            NetworkInfoDataItemBase(
-                    (NetworkType)type,
-                    type,
-                    typeName,
-                    subTypeName,
-                    connected && (!roaming),
-                    connected,
-                    roaming,
-                    networkHandle, apn),
-            mSrcObjPtr(nullptr) {}
-    inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) :
-            NetworkInfoDataItemBase(itemBase),
-            mSrcObjPtr((NetworkInfoDataItemBase*)&itemBase) {
-        mType = (int32_t)itemBase.getType();
-    }
-    inline bool equals(const SystemStatusNetworkInfo& peer) {
-        bool rtv = (peer.mConnected == mConnected);
+    NetworkInfoDataItem mDataItem;
+    inline SystemStatusNetworkInfo(int32_t type=0, std::string typeName="", string subTypeName="",
+            bool connected=false, bool roaming=false,
+            uint64_t networkHandle=NETWORK_HANDLE_UNKNOWN, string apn = "") :
+                mDataItem((NetworkType)type, type, typeName,
+                        subTypeName, connected && (!roaming), connected, roaming, networkHandle,
+                        apn) {}
+    inline SystemStatusNetworkInfo(const NetworkInfoDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        const NetworkInfoDataItem peerDI = ((const SystemStatusNetworkInfo&)peer).mDataItem;
+        bool rtv = (mDataItem.mAllTypes == peerDI.mAllTypes) &&
+                (mDataItem.mConnected == peerDI.mConnected);
         for (uint8_t i = 0; rtv && i < MAX_NETWORK_HANDLES; ++i) {
-            rtv &= (mAllNetworkHandles[i] == peer.mAllNetworkHandles[i]);
+            rtv = (mDataItem.mAllNetworkHandles[i] == peerDI.mAllNetworkHandles[i]) && rtv;
         }
-        return rtv && !peer.mApn.compare(mApn);
+        rtv = rtv && !peerDI.mApn.compare(mDataItem.mApn);
+        LOC_LOGv("NetworkInfoDataItem quals: %d", rtv);
+        return rtv;
     }
     inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) {
         LOC_LOGv("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x mApn=%s",
-                 mAllTypes, mConnected, mType, mApn.c_str());
-        uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mAllTypes;
-        string& apn = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mApn;
+                 mDataItem.mAllTypes, mDataItem.mConnected, mDataItem.mType,
+                 mDataItem.mApn.c_str());
+        uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mDataItem.mAllTypes;
+        string& apn = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mDataItem.mApn;
         // Replace current with cached table for now and then update
-        memcpy(mAllNetworkHandles,
-               (static_cast<SystemStatusNetworkInfo&>(curInfo)).getNetworkHandle(),
-               sizeof(mAllNetworkHandles));
-        // Update the apn for non-mobile type connections.
-        if (TYPE_MOBILE != mType && apn.compare("") != 0) {
-            mApn = apn;
-        }
-        if (mConnected) {
-            mAllTypes |= allTypes;
+        memcpy(mDataItem.mAllNetworkHandles,
+               static_cast<SystemStatusNetworkInfo&>(curInfo).mDataItem.getNetworkHandle(),
+               sizeof(mDataItem.mAllNetworkHandles));
+         // Update the apn for non-mobile type connections.
+         if (TYPE_MOBILE != mDataItem.mType && apn.compare("") != 0) {
+            mDataItem.mApn = apn;
+         }
+        if (mDataItem.mConnected) {
+            mDataItem.mAllTypes |= allTypes;
             for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
-                if (mNetworkHandle == mAllNetworkHandles[i].networkHandle) {
+                if (mDataItem.mNetworkHandle ==
+                        mDataItem.mAllNetworkHandles[i].networkHandle) {
                     LOC_LOGD("collate duplicate detected, not updating");
                     break;
                 }
-                if (NETWORK_HANDLE_UNKNOWN == mAllNetworkHandles[i].networkHandle) {
-                    mAllNetworkHandles[i].networkHandle = mNetworkHandle;
-                    mAllNetworkHandles[i].networkType = (loc_core::NetworkType) mType;
+                if (NETWORK_HANDLE_UNKNOWN ==
+                        mDataItem.mAllNetworkHandles[i].networkHandle) {
+                    mDataItem.mAllNetworkHandles[i].networkHandle =
+                            mDataItem.mNetworkHandle;
+                    mDataItem.mAllNetworkHandles[i].networkType =
+                            (loc_core::NetworkType) mDataItem.mType;
                     break;
                 }
             }
-        } else if (0 != mAllTypes) {
+        } else if (0 != mDataItem.mAllTypes) {
             uint8_t deletedIndex = MAX_NETWORK_HANDLES;
             uint8_t lastValidIndex = 0;
             uint8_t typeCount = 0;
-            for (; lastValidIndex < MAX_NETWORK_HANDLES &&
-                     NETWORK_HANDLE_UNKNOWN != mAllNetworkHandles[lastValidIndex].networkHandle;
+            for (; lastValidIndex < MAX_NETWORK_HANDLES && NETWORK_HANDLE_UNKNOWN !=
+                    mDataItem.mAllNetworkHandles[lastValidIndex].networkHandle;
                  ++lastValidIndex) {
                 // Maintain count for number of network handles still
                 // connected for given type
-                if (mType == (int32_t)mAllNetworkHandles[lastValidIndex].networkType) {
-                    if (mNetworkHandle == mAllNetworkHandles[lastValidIndex].networkHandle) {
+                if (mDataItem.mType ==
+                        mDataItem.mAllNetworkHandles[lastValidIndex].networkType) {
+                    if (mDataItem.mNetworkHandle ==
+                            mDataItem.mAllNetworkHandles[lastValidIndex].networkHandle) {
                         deletedIndex = lastValidIndex;
                     } else {
                         typeCount++;
@@ -562,264 +586,241 @@
             if (MAX_NETWORK_HANDLES != deletedIndex) {
                 LOC_LOGd("deletedIndex:%u, lastValidIndex:%u, typeCount:%u",
                         deletedIndex, lastValidIndex, typeCount);
-                mAllNetworkHandles[deletedIndex] = mAllNetworkHandles[lastValidIndex];
-                mAllNetworkHandles[lastValidIndex].networkHandle = NETWORK_HANDLE_UNKNOWN;
-                mAllNetworkHandles[lastValidIndex].networkType = TYPE_UNKNOWN;
+                mDataItem.mAllNetworkHandles[deletedIndex] =
+                        mDataItem.mAllNetworkHandles[lastValidIndex];
+                mDataItem.mAllNetworkHandles[lastValidIndex].networkHandle =
+                        NETWORK_HANDLE_UNKNOWN;
+                mDataItem.mAllNetworkHandles[lastValidIndex].networkType = TYPE_UNKNOWN;
             }
 
             // If no more handles of given type, set bitmask
             if (0 == typeCount) {
-                mAllTypes = (allTypes & (~mAllTypes));
-                LOC_LOGD("mAllTypes:%" PRIx64, mAllTypes);
+                mDataItem.mAllTypes = (allTypes & (~mDataItem.mAllTypes));
+                LOC_LOGD("mAllTypes:%" PRIx64, mDataItem.mAllTypes);
             }
-        } // else (mConnected == false && mAllTypes == 0)
-          // we keep mAllTypes as 0, which means no more connections.
-
-        if (nullptr != mSrcObjPtr) {
-            // this is critical, changing mAllTypes of the original obj
-            mSrcObjPtr->mAllTypes = mAllTypes;
-            memcpy(mSrcObjPtr->mAllNetworkHandles,
-                   mAllNetworkHandles,
-                   sizeof(mSrcObjPtr->mAllNetworkHandles));
-        }
+        } // else (mDataItem.mConnected == false && mDataItem.mAllTypes == 0)
+          // we keep mDataItem->mAllTypes as 0, which means no more connections.
         return *this;
     }
     inline void dump(void) override {
         LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x mApn=%s",
-                 mAllTypes, mConnected, mType, mApn.c_str());
+                mDataItem.mAllTypes, mDataItem.mConnected, mDataItem.mType, mDataItem.mApn.c_str());
     }
 };
 
-class SystemStatusServiceInfo : public SystemStatusItemBase,
-        public RilServiceInfoDataItemBase
-{
+class SystemStatusServiceInfo : public SystemStatusItemBase {
 public:
-    inline SystemStatusServiceInfo() :
-            RilServiceInfoDataItemBase() {}
-    inline SystemStatusServiceInfo(const RilServiceInfoDataItemBase& itemBase) :
-            RilServiceInfoDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusServiceInfo& peer) {
-        return static_cast<const RilServiceInfoDataItemBase&>(peer) ==
-                static_cast<const RilServiceInfoDataItemBase&>(*this);
+    RilServiceInfoDataItem mDataItem;
+    inline SystemStatusServiceInfo(): mDataItem() {}
+    inline SystemStatusServiceInfo(const RilServiceInfoDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return ((const SystemStatusServiceInfo&)peer).mDataItem == mDataItem;
     }
 };
 
-class SystemStatusRilCellInfo : public SystemStatusItemBase,
-        public RilCellInfoDataItemBase
-{
+class SystemStatusRilCellInfo : public SystemStatusItemBase {
 public:
-    inline SystemStatusRilCellInfo() :
-            RilCellInfoDataItemBase() {}
-    inline SystemStatusRilCellInfo(const RilCellInfoDataItemBase& itemBase) :
-            RilCellInfoDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusRilCellInfo& peer) {
-        return static_cast<const RilCellInfoDataItemBase&>(peer) ==
-                static_cast<const RilCellInfoDataItemBase&>(*this);
+    RilCellInfoDataItem mDataItem;
+    inline SystemStatusRilCellInfo(): mDataItem() {}
+    inline SystemStatusRilCellInfo(const RilCellInfoDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return ((const SystemStatusRilCellInfo&)peer).mDataItem == mDataItem;
     }
 };
 
-class SystemStatusServiceStatus : public SystemStatusItemBase,
-        public ServiceStatusDataItemBase
-{
+class SystemStatusServiceStatus : public SystemStatusItemBase {
 public:
-    inline SystemStatusServiceStatus(int32_t mServiceState=0) :
-            ServiceStatusDataItemBase(mServiceState) {}
-    inline SystemStatusServiceStatus(const ServiceStatusDataItemBase& itemBase) :
-            ServiceStatusDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusServiceStatus& peer) {
-        return (mServiceState == peer.mServiceState);
+    ServiceStatusDataItem mDataItem;
+    inline SystemStatusServiceStatus(int32_t mServiceState=0): mDataItem(mServiceState) {}
+    inline SystemStatusServiceStatus(const ServiceStatusDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mServiceState ==
+                ((const SystemStatusServiceStatus&)peer).mDataItem.mServiceState;
     }
 };
 
-class SystemStatusModel : public SystemStatusItemBase,
-        public ModelDataItemBase
-{
+class SystemStatusModel : public SystemStatusItemBase {
 public:
-    inline SystemStatusModel(string name="") :
-            ModelDataItemBase(name) {}
-    inline SystemStatusModel(const ModelDataItemBase& itemBase) :
-            ModelDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusModel& peer) {
-        return (mModel == peer.mModel);
-        }
-};
-
-class SystemStatusManufacturer : public SystemStatusItemBase,
-        public ManufacturerDataItemBase
-{
-public:
-    inline SystemStatusManufacturer(string name="") :
-            ManufacturerDataItemBase(name) {}
-    inline SystemStatusManufacturer(const ManufacturerDataItemBase& itemBase) :
-            ManufacturerDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusManufacturer& peer) {
-        return (mManufacturer == peer.mManufacturer);
+    ModelDataItem mDataItem;
+    inline SystemStatusModel(string name=""): mDataItem(name) {}
+    inline SystemStatusModel(const ModelDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mModel == ((const SystemStatusModel&)peer).mDataItem.mModel;
     }
 };
 
-class SystemStatusAssistedGps : public SystemStatusItemBase,
-        public AssistedGpsDataItemBase
-{
+class SystemStatusManufacturer : public SystemStatusItemBase {
 public:
-    inline SystemStatusAssistedGps(bool enabled=false) :
-            AssistedGpsDataItemBase(enabled) {}
-    inline SystemStatusAssistedGps(const AssistedGpsDataItemBase& itemBase) :
-            AssistedGpsDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusAssistedGps& peer) {
-        return (mEnabled == peer.mEnabled);
+    ManufacturerDataItem mDataItem;
+    inline SystemStatusManufacturer(string name=""): mDataItem(name) {}
+    inline SystemStatusManufacturer(const ManufacturerDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mManufacturer ==
+                ((const SystemStatusManufacturer&)peer).mDataItem.mManufacturer;
     }
 };
 
-class SystemStatusScreenState : public SystemStatusItemBase,
-        public ScreenStateDataItemBase
-{
+class SystemStatusAssistedGps : public SystemStatusItemBase {
 public:
-    inline SystemStatusScreenState(bool state=false) :
-            ScreenStateDataItemBase(state) {}
-    inline SystemStatusScreenState(const ScreenStateDataItemBase& itemBase) :
-            ScreenStateDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusScreenState& peer) {
-        return (mState == peer.mState);
+    AssistedGpsDataItem mDataItem;
+    inline SystemStatusAssistedGps(bool enabled=false): mDataItem(enabled) {}
+    inline SystemStatusAssistedGps(const AssistedGpsDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mEnabled == ((const SystemStatusAssistedGps&)peer).mDataItem.mEnabled;
     }
 };
 
-class SystemStatusPowerConnectState : public SystemStatusItemBase,
-        public PowerConnectStateDataItemBase
-{
+class SystemStatusScreenState : public SystemStatusItemBase {
 public:
-    inline SystemStatusPowerConnectState(bool state=false) :
-            PowerConnectStateDataItemBase(state) {}
-    inline SystemStatusPowerConnectState(const PowerConnectStateDataItemBase& itemBase) :
-            PowerConnectStateDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusPowerConnectState& peer) {
-        return (mState == peer.mState);
+    ScreenStateDataItem mDataItem;
+    inline SystemStatusScreenState(bool state=false): mDataItem(state) {}
+    inline SystemStatusScreenState(const ScreenStateDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mState == ((const SystemStatusScreenState&)peer).mDataItem.mState;
     }
 };
 
-class SystemStatusTimeZoneChange : public SystemStatusItemBase,
-        public TimeZoneChangeDataItemBase
-{
+class SystemStatusPowerConnectState : public SystemStatusItemBase {
 public:
-    inline SystemStatusTimeZoneChange(
-            int64_t currTimeMillis=0ULL, int32_t rawOffset=0, int32_t dstOffset=0) :
-            TimeZoneChangeDataItemBase(currTimeMillis, rawOffset, dstOffset) {}
-    inline SystemStatusTimeZoneChange(const TimeZoneChangeDataItemBase& itemBase) :
-            TimeZoneChangeDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusTimeZoneChange& peer) {
-        return ((mCurrTimeMillis == peer.mCurrTimeMillis) &&
-                (mRawOffsetTZ == peer.mRawOffsetTZ) &&
-                (mDstOffsetTZ == peer.mDstOffsetTZ));
+    PowerConnectStateDataItem mDataItem;
+    inline SystemStatusPowerConnectState(bool state=false): mDataItem(state) {}
+    inline SystemStatusPowerConnectState(const PowerConnectStateDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mState == ((const SystemStatusPowerConnectState&)peer).mDataItem.mState;
     }
 };
 
-class SystemStatusTimeChange : public SystemStatusItemBase,
-        public TimeChangeDataItemBase
-{
+class SystemStatusTimeZoneChange : public SystemStatusItemBase {
 public:
+    TimeZoneChangeDataItem mDataItem;
+    inline SystemStatusTimeZoneChange(int64_t currTimeMillis=0ULL, int32_t rawOffset=0,
+            int32_t dstOffset=0): mDataItem(currTimeMillis, rawOffset, dstOffset) {}
+    inline SystemStatusTimeZoneChange(const TimeZoneChangeDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mCurrTimeMillis ==
+                ((const SystemStatusTimeZoneChange&)peer).mDataItem.mCurrTimeMillis &&
+                mDataItem.mRawOffsetTZ ==
+                ((const SystemStatusTimeZoneChange&)peer).mDataItem.mRawOffsetTZ &&
+                mDataItem.mDstOffsetTZ ==
+                ((const SystemStatusTimeZoneChange&)peer).mDataItem.mDstOffsetTZ;
+    }
+};
+
+class SystemStatusTimeChange : public SystemStatusItemBase {
+public:
+    TimeChangeDataItem mDataItem;
     inline SystemStatusTimeChange(
-            int64_t currTimeMillis=0ULL, int32_t rawOffset=0, int32_t dstOffset=0) :
-            TimeChangeDataItemBase(currTimeMillis, rawOffset, dstOffset) {}
-    inline SystemStatusTimeChange(const TimeChangeDataItemBase& itemBase) :
-            TimeChangeDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusTimeChange& peer) {
-        return ((mCurrTimeMillis == peer.mCurrTimeMillis) &&
-                (mRawOffsetTZ == peer.mRawOffsetTZ) &&
-                (mDstOffsetTZ == peer.mDstOffsetTZ));
+        int64_t currTimeMillis=0ULL, int32_t rawOffset=0, int32_t dstOffset=0):
+        mDataItem(currTimeMillis, rawOffset, dstOffset) {}
+    inline SystemStatusTimeChange(const TimeChangeDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mCurrTimeMillis ==
+                ((const SystemStatusTimeChange&)peer).mDataItem.mCurrTimeMillis &&
+                mDataItem.mRawOffsetTZ ==
+                ((const SystemStatusTimeChange&)peer).mDataItem.mRawOffsetTZ &&
+                mDataItem.mDstOffsetTZ ==
+                ((const SystemStatusTimeChange&)peer).mDataItem.mDstOffsetTZ;
     }
 };
 
-class SystemStatusWifiSupplicantStatus : public SystemStatusItemBase,
-        public WifiSupplicantStatusDataItemBase
-{
+class SystemStatusWifiSupplicantStatus : public SystemStatusItemBase {
 public:
-    inline SystemStatusWifiSupplicantStatus() :
-            WifiSupplicantStatusDataItemBase() {}
-    inline SystemStatusWifiSupplicantStatus(const WifiSupplicantStatusDataItemBase& itemBase) :
-            WifiSupplicantStatusDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusWifiSupplicantStatus& peer) {
-        return ((mState == peer.mState) &&
-                (mApMacAddressValid == peer.mApMacAddressValid) &&
-                (mWifiApSsidValid == peer.mWifiApSsidValid) &&
-                (mWifiApSsid == peer.mWifiApSsid));
+    WifiSupplicantStatusDataItem mDataItem;
+    inline SystemStatusWifiSupplicantStatus(): mDataItem() {}
+    inline SystemStatusWifiSupplicantStatus(const WifiSupplicantStatusDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mState ==
+                ((const SystemStatusWifiSupplicantStatus&)peer).mDataItem.mState &&
+                mDataItem.mApMacAddressValid ==
+                ((const SystemStatusWifiSupplicantStatus&)peer).mDataItem.mApMacAddressValid &&
+                mDataItem.mWifiApSsidValid ==
+                ((const SystemStatusWifiSupplicantStatus&)peer).mDataItem.mWifiApSsidValid &&
+                mDataItem.mWifiApSsid ==
+                ((const SystemStatusWifiSupplicantStatus&)peer).mDataItem.mWifiApSsid;
         }
 };
 
-class SystemStatusShutdownState : public SystemStatusItemBase,
-        public ShutdownStateDataItemBase
-{
+class SystemStatusShutdownState : public SystemStatusItemBase {
 public:
-    inline SystemStatusShutdownState(bool state=false) :
-            ShutdownStateDataItemBase(state) {}
-    inline SystemStatusShutdownState(const ShutdownStateDataItemBase& itemBase) :
-            ShutdownStateDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusShutdownState& peer) {
-        return (mState == peer.mState);
+    ShutdownStateDataItem mDataItem;
+    inline SystemStatusShutdownState(bool state=false): mDataItem(state) {}
+    inline SystemStatusShutdownState(const ShutdownStateDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mState == ((const SystemStatusShutdownState&)peer).mDataItem.mState;
     }
 };
 
-class SystemStatusTac : public SystemStatusItemBase,
-        public TacDataItemBase
-{
+class SystemStatusTac : public SystemStatusItemBase {
 public:
-    inline SystemStatusTac(std::string value="") :
-            TacDataItemBase(value) {}
-    inline SystemStatusTac(const TacDataItemBase& itemBase) :
-            TacDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusTac& peer) {
-        return (mValue == peer.mValue);
+    TacDataItem mDataItem;
+    inline SystemStatusTac(std::string value=""): mDataItem(value) {}
+    inline SystemStatusTac(const TacDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mValue == ((const SystemStatusTac&)peer).mDataItem.mValue;
     }
     inline void dump(void) override {
-        LOC_LOGD("Tac: value=%s", mValue.c_str());
+        LOC_LOGD("Tac: value=%s", mDataItem.mValue.c_str());
     }
 };
 
-class SystemStatusMccMnc : public SystemStatusItemBase,
-        public MccmncDataItemBase
-{
+class SystemStatusMccMnc : public SystemStatusItemBase {
 public:
-    inline SystemStatusMccMnc(std::string value="") :
-            MccmncDataItemBase(value) {}
-    inline SystemStatusMccMnc(const MccmncDataItemBase& itemBase) :
-            MccmncDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusMccMnc& peer) {
-        return (mValue == peer.mValue);
+    MccmncDataItem mDataItem;
+    inline SystemStatusMccMnc(std::string value=""): mDataItem(value) {}
+    inline SystemStatusMccMnc(const MccmncDataItem& itemBase): mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mValue == ((const SystemStatusMccMnc&)peer).mDataItem.mValue;
     }
     inline void dump(void) override {
-        LOC_LOGD("TacMccMnc value=%s", mValue.c_str());
+        LOC_LOGD("TacMccMnc value=%s", mDataItem.mValue.c_str());
     }
 };
 
-class SystemStatusBtDeviceScanDetail : public SystemStatusItemBase,
-        public BtDeviceScanDetailsDataItemBase
-{
+class SystemStatusBtDeviceScanDetail : public SystemStatusItemBase {
 public:
-    inline SystemStatusBtDeviceScanDetail() :
-            BtDeviceScanDetailsDataItemBase() {}
-    inline SystemStatusBtDeviceScanDetail(const BtDeviceScanDetailsDataItemBase& itemBase) :
-            BtDeviceScanDetailsDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusBtDeviceScanDetail& peer) {
-        return ((mApSrnRssi == peer.mApSrnRssi) &&
-                (0 == memcmp(mApSrnMacAddress, peer.mApSrnMacAddress, sizeof(mApSrnMacAddress))) &&
-                (mApSrnTimestamp == peer.mApSrnTimestamp) &&
-                (mRequestTimestamp == peer.mRequestTimestamp) &&
-                (mReceiveTimestamp == peer.mReceiveTimestamp));
+    BtDeviceScanDetailsDataItem mDataItem;
+    inline SystemStatusBtDeviceScanDetail(): mDataItem() {}
+    inline SystemStatusBtDeviceScanDetail(const BtDeviceScanDetailsDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mApSrnRssi ==
+                ((const SystemStatusBtDeviceScanDetail&)peer).mDataItem.mApSrnRssi &&
+                memcmp(mDataItem.mApSrnMacAddress,
+                ((const SystemStatusBtDeviceScanDetail&)peer).mDataItem.mApSrnMacAddress,
+                sizeof(mDataItem.mApSrnMacAddress)) == 0 &&
+                mDataItem.mApSrnTimestamp ==
+                ((const SystemStatusBtDeviceScanDetail&)peer).mDataItem.mApSrnTimestamp &&
+                mDataItem.mRequestTimestamp ==
+                ((const SystemStatusBtDeviceScanDetail&)peer).mDataItem.mRequestTimestamp &&
+                mDataItem.mReceiveTimestamp ==
+                ((const SystemStatusBtDeviceScanDetail&)peer).mDataItem.mReceiveTimestamp;
     }
 };
 
-class SystemStatusBtleDeviceScanDetail : public SystemStatusItemBase,
-        public BtLeDeviceScanDetailsDataItemBase
-{
+class SystemStatusBtleDeviceScanDetail : public SystemStatusItemBase {
 public:
-    inline SystemStatusBtleDeviceScanDetail() :
-            BtLeDeviceScanDetailsDataItemBase() {}
-    inline SystemStatusBtleDeviceScanDetail(const BtLeDeviceScanDetailsDataItemBase& itemBase) :
-            BtLeDeviceScanDetailsDataItemBase(itemBase) {}
-    inline bool equals(const SystemStatusBtleDeviceScanDetail& peer) {
-        return ((mApSrnRssi == peer.mApSrnRssi) &&
-                (0 == memcmp(mApSrnMacAddress, peer.mApSrnMacAddress, sizeof(mApSrnMacAddress))) &&
-                (mApSrnTimestamp == peer.mApSrnTimestamp) &&
-                (mRequestTimestamp == peer.mRequestTimestamp) &&
-                (mReceiveTimestamp == peer.mReceiveTimestamp));
+    BtLeDeviceScanDetailsDataItem mDataItem;
+    inline SystemStatusBtleDeviceScanDetail(): mDataItem() {}
+    inline SystemStatusBtleDeviceScanDetail(const BtLeDeviceScanDetailsDataItem& itemBase):
+            mDataItem(itemBase) {}
+    inline bool equals(const SystemStatusItemBase& peer) override {
+        return mDataItem.mApSrnRssi ==
+                ((const SystemStatusBtleDeviceScanDetail&)peer).mDataItem.mApSrnRssi &&
+                memcmp(mDataItem.mApSrnMacAddress,
+                ((const SystemStatusBtleDeviceScanDetail&)peer).mDataItem.mApSrnMacAddress,
+                sizeof(mDataItem.mApSrnMacAddress)) == 0 &&
+                mDataItem.mApSrnTimestamp ==
+                ((const SystemStatusBtleDeviceScanDetail&)peer).mDataItem.mApSrnTimestamp &&
+                mDataItem.mRequestTimestamp ==
+                ((const SystemStatusBtleDeviceScanDetail&)peer).mDataItem.mRequestTimestamp &&
+                mDataItem.mReceiveTimestamp ==
+                ((const SystemStatusBtleDeviceScanDetail&)peer).mDataItem.mReceiveTimestamp;
     }
 };
 
@@ -918,6 +919,8 @@
                                bool roaming, NetworkHandle networkHandle, string& apn);
     bool updatePowerConnectState(bool charging);
     void resetNetworkInfo();
+    bool eventOptInStatus(bool userConsent);
+    bool eventRegionStatus(bool region);
 };
 
 } // namespace loc_core
diff --git a/gps/core/SystemStatusOsObserver.cpp b/gps/core/SystemStatusOsObserver.cpp
index 8fd9564..c41c715 100644
--- a/gps/core/SystemStatusOsObserver.cpp
+++ b/gps/core/SystemStatusOsObserver.cpp
@@ -46,9 +46,6 @@
 }
 
 SystemStatusOsObserver::~SystemStatusOsObserver() {
-    // Close data-item library handle
-    DataItemsFactoryProxy::closeDataItemLibraryHandle();
-
     // Destroy cache
     for (auto each : mDataItemCache) {
         if (nullptr != each.second) {
@@ -112,10 +109,10 @@
             // Send subscription set to framework
             if (nullptr != mParent->mContext.mSubscriptionObj) {
                 if (mToRequestData) {
-                    LOC_LOGD("Request Data sent to framework for the following");
+                    LOC_LOGd("Request Data sent to framework for the following");
                     mParent->mContext.mSubscriptionObj->requestData(diItemlist, mParent);
                 } else if (!dataItemsToSubscribe.empty()) {
-                    LOC_LOGD("Subscribe Request sent to framework for the following");
+                    LOC_LOGd("Subscribe Request sent to framework for the following");
                     mParent->logMe(dataItemsToSubscribe);
                     mParent->mContext.mSubscriptionObj->subscribe(
                             containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
@@ -177,7 +174,7 @@
             if (nullptr != mParent->mContext.mSubscriptionObj) {
                 // Send subscription set to framework
                 if (!dataItemsToSubscribe.empty()) {
-                    LOC_LOGD("Subscribe Request sent to framework for the following");
+                    LOC_LOGd("Subscribe Request sent to framework for the following");
                     mParent->logMe(dataItemsToSubscribe);
 
                     mParent->mContext.mSubscriptionObj->subscribe(
@@ -188,7 +185,7 @@
 
                 // Send unsubscribe to framework
                 if (!dataItemsToUnsubscribe.empty()) {
-                    LOC_LOGD("Unsubscribe Request sent to framework for the following");
+                    LOC_LOGd("Unsubscribe Request sent to framework for the following");
                     mParent->logMe(dataItemsToUnsubscribe);
 
                     mParent->mContext.mSubscriptionObj->unsubscribe(
@@ -230,7 +227,7 @@
                                                      &dataItemsToUnsubscribe, nullptr);
 
             if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToUnsubscribe.empty()) {
-                LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
+                LOC_LOGd("Unsubscribe Request sent to framework for the following data items");
                 mParent->logMe(dataItemsToUnsubscribe);
 
                 // Send unsubscribe to framework
@@ -271,7 +268,7 @@
                 if (!dataItemsToUnsubscribe.empty() &&
                     nullptr != mParent->mContext.mSubscriptionObj) {
 
-                    LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
+                    LOC_LOGd("Unsubscribe Request sent to framework for the following data items");
                     mParent->logMe(dataItemsToUnsubscribe);
 
                     // Send unsubscribe to framework
@@ -347,19 +344,16 @@
     };
 
     if (!dlist.empty()) {
-        vector<IDataItemCore*> dataItemVec(dlist.size());
+        vector<IDataItemCore*> dataItemVec;
 
         for (auto each : dlist) {
 
-            IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
+            IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each);
             if (nullptr == di) {
                 LOC_LOGw("Unable to create dataitem:%d", each->getId());
                 continue;
             }
 
-            // Copy contents into the newly created data item
-            di->copy(each);
-
             // add this dataitem if updated from last one
             dataItemVec.push_back(di);
             IF_LOC_LOGD {
@@ -381,7 +375,7 @@
 void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
 {
     if (nullptr == mContext.mFrameworkActionReqObj) {
-        LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
+        LOC_LOGe("Framework action request object is NULL");
         return;
     }
 
@@ -392,7 +386,7 @@
         // Add reference count as 1 and add dataitem to map
         pair<DataItemId, int> cpair(dit, 1);
         mActiveRequestCount.insert(cpair);
-        LOC_LOGD("Sending turnOn request");
+        LOC_LOGd("Sending turnOn request");
 
         // Send action turn on to framework
         struct HandleTurnOnMsg : public LocMsg {
@@ -413,14 +407,14 @@
     else {
         // Found in map, update reference count
         citer->second++;
-        LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second);
+        LOC_LOGd("turnOn - Data item:%d Num_refs:%d", dit, citer->second);
     }
 }
 
 void SystemStatusOsObserver::turnOff(DataItemId dit)
 {
     if (nullptr == mContext.mFrameworkActionReqObj) {
-        LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
+        LOC_LOGe("Framework action request object is NULL");
         return;
     }
 
@@ -429,7 +423,7 @@
     if (citer != mActiveRequestCount.end()) {
         // found
         citer->second--;
-        LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second);
+        LOC_LOGd("turnOff - Data item:%d Remaining:%d", dit, citer->second);
         if(citer->second == 0) {
             // if this was last reference, remove item from map and turn off module
             mActiveRequestCount.erase(citer);
@@ -542,7 +536,7 @@
             if (citer != mDataItemCache.end()) {
                 string dv;
                 citer->second->stringify(dv);
-                LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
+                LOC_LOGi("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
                 dataItems.push_front(citer->second);
             }
         }
@@ -564,27 +558,22 @@
     // handling it, so SystemStatusOsObserver also doesn't.
     // So it has to be true to proceed.
     if (nullptr != d && mSystemStatus->eventDataItemNotify(d)) {
+        dataItemUpdated = true;
         auto citer = mDataItemCache.find(d->getId());
         if (citer == mDataItemCache.end()) {
             // New data item; not found in cache
-            IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
+            IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d);
             if (nullptr != dataitem) {
-                // Copy the contents of the data item
-                dataitem->copy(d);
                 // Insert in mDataItemCache
                 mDataItemCache.insert(std::make_pair(d->getId(), dataitem));
-                dataItemUpdated = true;
             }
         } else {
             // Found in cache; Update cache if necessary
-            citer->second->copy(d, &dataItemUpdated);
-        }
-
-        if (dataItemUpdated) {
-            LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
+            citer->second->copyFrom(d);
         }
     }
 
+    LOC_LOGd("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
     return dataItemUpdated;
 }
 
diff --git a/gps/core/data-items/DataItemConcreteTypes.cpp b/gps/core/data-items/DataItemConcreteTypes.cpp
new file mode 100644
index 0000000..56ef96f
--- /dev/null
+++ b/gps/core/data-items/DataItemConcreteTypes.cpp
@@ -0,0 +1,924 @@
+/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+Changes from Qualcomm Innovation Center are provided under the following license:
+Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+SPDX-License-Identifier: BSD-3-Clause-Clear
+*/
+
+#include "DataItemConcreteTypes.h"
+#include <inttypes.h>
+#include <log_util.h>
+
+#define ENH_FIELD_ENABLED "IS_QUALCOMM_ENHANCED_PROVIDER_ENABLED"
+#define AIRPLANEMODE_FIELD_MODE "IS_AIRPLANE_MODE_ON"
+#define ENH_FIELD_ENABLED "IS_QUALCOMM_ENHANCED_PROVIDER_ENABLED"
+#define GPSSTATE_FIELD_ENABLED "IS_GPS_PROVIDER_ENABLED"
+#define NLPSTATUS_FIELD_ENABLED "IS_NETWORK_PROVIDER_ENABLED"
+#define WIFIHARDWARESTATE_FIELD_ENABLED "IS_WIFI_HARDWARE_ON"
+#define SCREENSTATE_FIELD_ENABLED "IS_SCREEN_ON"
+#define POWERCONNECTSTATE_FIELD_ENABLED "IS_POWER_CONNECTED"
+#define TIMEZONECHANGE_FIELD_ENABLED "IS_TIMEZONE_CHANGED"
+#define TIMECHANGE_FIELD_ENABLED "IS_TIME_CHANGED"
+#define TIMECHANGE_FIELD_CURRENT_TIME_MILLIS "CURR_TIME_MILLIS"
+#define TIMECHANGE_FIELD_RAW_OFFSET_TZ "RAW_OFFSET_TZ"
+#define TIMECHANGE_FIELD_DST_OFFSET_TZ "DST_OFFSET_TZ"
+
+#define SHUTDOWN_FIELD_ENABLED "IS_SHUTDOWN"
+#define ASSISTEDGPS_FIELD_ENABLED "IS_ASSISTED_GPS_ENABLED"
+
+#define NETWORKINFO_CARD "ACTIVE_NETWORK_INFO"
+#define NETWORKINFO_FIELD_TYPE "TYPE"
+#define NETWORKINFO_FIELD_TYPENAME "TYPE_NAME"
+#define NETWORKINFO_FIELD_SUBTYPENAME "SUB_TYPE_NAME"
+#define NETWORKINFO_FIELD_AVAILABLE "IS_AVAILABLE"
+#define NETWORKINFO_FIELD_CONNECTED "IS_CONNECTED"
+#define NETWORKINFO_FIELD_ROAMING "IS_ROAMING"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_0 "NETWORK_HANDLE_0"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_1 "NETWORK_HANDLE_1"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_2 "NETWORK_HANDLE_2"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_3 "NETWORK_HANDLE_3"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_4 "NETWORK_HANDLE_4"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_5 "NETWORK_HANDLE_5"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_6 "NETWORK_HANDLE_6"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_7 "NETWORK_HANDLE_7"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_8 "NETWORK_HANDLE_8"
+#define NETWORKINFO_FIELD_NETWORKHANDLE_9 "NETWORK_HANDLE_9"
+
+#define SERVICESTATUS_FIELD_STATE "CELL_NETWORK_STATUS"
+#define MODEL_FIELD_NAME "MODEL"
+#define MANUFACTURER_FIELD_NAME "MANUFACTURER"
+#define OSSTATUS_CARD "ACTIVE_NETWORK_INFO"
+
+#define RILSERVICEINFO_CARD "RIL-SERVICE-INFO"
+#define RILSERVICEINFO_FIELD_ARIF_TYPE_MASK "SUPPORTED-AIRINTERFACE-TYPE-MASK"
+#define RILSERVICEINFO_FIELD_CARRIER_ARIF_TYPE "CARRIER-AIRINTERFACE-TYPE"
+#define RILSERVICEINFO_FIELD_CARRIER_MCC "MOBILE-COUNTRY-CODE"
+#define RILSERVICEINFO_FIELD_CARRIER_MNC "MOBILE-NETWORK-CODE"
+#define RILSERVICEINFO_FIELD_CARRIER_NAME "HOME-CARRIER-NAME"
+
+#define RILCELLINFO_CARD "RIL-CELL-UPDATE"
+#define RILCELLINFO_FIELD_NETWORK_STATUS "NETWORK-STATUS"
+#define RILCELLINFO_FIELD_RIL_TECH_TYPE "RIL-TECH-TYPE"
+#define RILLCELLINFO_FIELD_MCC "MOBILE-COUNTRY-CODE"
+#define RILLCELLINFO_FIELD_MNC "MOBILE-NETWORK-CODE"
+#define RILLCELLINFO_FIELD_LAC "LOCATION-AREA-CODE"
+#define RILLCELLINFO_FIELD_CID "CELL-ID"
+#define RILLCELLINFO_FIELD_SID "SYSTEM-ID"
+#define RILLCELLINFO_FIELD_NID "NETWORK-ID"
+#define RILLCELLINFO_FIELD_BSID "BASE-STATION-ID"
+#define RILLCELLINFO_FIELD_BSLAT "BASE-STATION-LATITUDE"
+#define RILLCELLINFO_FIELD_BSLON "BASE-STATION-LONGITUDE"
+#define RILLCELLINFO_FIELD_UTC_TIME_OFFSET "TIME-ZONE-OFFSET"
+#define RILLCELLINFO_FIELD_DAYLIGHT_TIMEZONE "IN-DAY-LIGHT-SAVING"
+#define RILLCELLINFO_FIELD_TAC "TRACKING-AREA-CODE"
+#define RILLCELLINFO_FIELD_PCI "PHYSICAL-CELL-ID"
+#define RILLCELLINFO_FIELD_NB_MODE "NB-MODE"
+#define RILLCELLINFO_FIELD_NB_EARFCN_OFFSET "NB-EARFCN-OFFSET"
+
+#define WIFI_SUPPLICANT_FIELD_STATE "WIFI-SUPPLICANT-STATE"
+#define TAC_FIELD_NAME "TAC"
+#define MCCMNC_FIELD_NAME "MCCMNC"
+
+#define BTLESCANDETAILS_FIELD_VALID "BTLE_VALID_DEV"
+#define BTLESCANDETAILS_FIELD_RSSI "BTLE_DEV_RSSI"
+#define BTLESCANDETAILS_FIELD_MAC "BTLE_DEV_MAC"
+#define BTLESCANDETAILS_FIELD_SCANREQ "BTLE_SCAN_REQ_TIME"
+#define BTLESCANDETAILS_FIELD_SCANSTART "BTLE_SCAN_START_TIME"
+#define BTLESCANDETAILS_FIELD_SCANRECV "BTLE_SCAN_RECV_TIME"
+#define BTLESCANDETAILS_FIELD_SCANERROR "BTLE_SCAN_ERR"
+
+#define BTSCANDETAILS_FIELD_VALID "BT_VALID_DEV"
+#define BTSCANDETAILS_FIELD_RSSI "BT_DEV_RSSI"
+#define BTSCANDETAILS_FIELD_MAC "BT_DEV_MAC"
+#define BTSCANDETAILS_FIELD_SCANREQ "BT_SCAN_REQ_TIME"
+#define BTSCANDETAILS_FIELD_SCANSTART "BT_SCAN_START_TIME"
+#define BTSCANDETAILS_FIELD_SCANRECV "BT_SCAN_RECV_TIME"
+#define BTSCANDETAILS_FIELD_SCANERROR "BT_SCAN_ERR"
+
+#define OEM_GTP_UPLAOD_TRIGGER_READY_FIELD_NAME "OEM-GTP-UPLOAD-TRIGGER-READY"
+#define BATTERYLEVEL_FIELD_BATTERY_PCT "BATTERY_PCT"
+
+namespace loc_core
+{
+// stringify
+void AirplaneModeDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(AirplaneModeDataItem, AIRPLANEMODE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = AIRPLANEMODE_FIELD_MODE;
+        valueStr += ": ";
+        valueStr += (d->mMode) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+
+void ENHDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(ENHDataItem, ENH_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = ENH_FIELD_ENABLED;
+        if (!d->isEnabled()) {
+            Fields field = FIELD_MAX;
+            switch (mFieldUpdate) {
+                case FIELD_CONSENT:
+                    valueStr += "_FIELD_CONSENT";
+                    field = FIELD_CONSENT;
+                    break;
+                case FIELD_REGION:
+                    valueStr += "_FIELD_REGION";
+                    field = FIELD_REGION;
+                    break;
+                default:
+                    break;
+            }
+            valueStr += ": ";
+            valueStr += (((1 << field) & d->mEnhFields) != 0) ? "true" : "false";
+        } else {
+            valueStr += ": ";
+            valueStr += "true";
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void GPSStateDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(GPSStateDataItem, GPSSTATE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = GPSSTATE_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += (d->mEnabled) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void NLPStatusDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(NLPStatusDataItem, NLPSTATUS_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = NLPSTATUS_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += (d->mEnabled) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void WifiHardwareStateDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(WifiHardwareStateDataItem,
+                WIFIHARDWARESTATE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = WIFIHARDWARESTATE_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += (d->mEnabled) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void ScreenStateDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(ScreenStateDataItem, SCREEN_STATE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = SCREENSTATE_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += (d->mState) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void PowerConnectStateDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(PowerConnectStateDataItem,
+                POWER_CONNECTED_STATE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = POWERCONNECTSTATE_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += (d->mState) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+
+void BatteryLevelDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(BatteryLevelDataItem, BATTERY_LEVEL_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr += BATTERYLEVEL_FIELD_BATTERY_PCT;
+        valueStr += ": ";
+        char state [12];
+        snprintf (state, 12, "%d", d->mBatteryPct);
+        valueStr += string (state);
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+
+void TimeZoneChangeDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(TimeZoneChangeDataItem, TIMEZONE_CHANGE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = TIMEZONECHANGE_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += "true";
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void TimeChangeDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(TimeChangeDataItem, TIME_CHANGE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = TIMECHANGE_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += "true";
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void ShutdownStateDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(ShutdownStateDataItem, SHUTDOWN_STATE_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = SHUTDOWN_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += (d->mState) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void AssistedGpsDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(AssistedGpsDataItem, ASSISTED_GPS_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = ASSISTEDGPS_FIELD_ENABLED;
+        valueStr += ": ";
+        valueStr += (d->mEnabled) ? ("true") : ("false");
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void NetworkInfoDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(NetworkInfoDataItem, NETWORKINFO_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr = NETWORKINFO_CARD;
+        valueStr += "::";
+        valueStr += NETWORKINFO_FIELD_TYPE;
+        valueStr += "s_MASK: ";
+        char type [12];
+        snprintf (type, 12, "%" PRIu64, mAllTypes);
+        valueStr += string (type);
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_TYPENAME;
+        valueStr += ": ";
+        valueStr += d->mTypeName;
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_SUBTYPENAME;
+        valueStr += ": ";
+        valueStr += d->mSubTypeName;
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_AVAILABLE;
+        valueStr += ": ";
+        valueStr += (d->mAvailable) ? ("true") : ("false");
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_CONNECTED;
+        valueStr += ": ";
+        valueStr += (d->mConnected) ? ("true") : ("false");
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_ROAMING;
+        valueStr += ": ";
+        valueStr += (d->mRoaming) ? ("true") : ("false");
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_0;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[0].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_1;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[1].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_2;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[2].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_3;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[3].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_4;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[4].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_5;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[5].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_6;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[6].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_7;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[7].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_8;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[8].toString();
+        valueStr += ", ";
+        valueStr += NETWORKINFO_FIELD_NETWORKHANDLE_9;
+        valueStr += ": ";
+        valueStr += d->mAllNetworkHandles[9].toString();
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void ServiceStatusDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(ServiceStatusDataItem, SERVICESTATUS_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr += SERVICESTATUS_FIELD_STATE;
+        valueStr += ": ";
+        char state [12];
+        snprintf (state, 12, "%d", d->mServiceState);
+        valueStr += string (state);
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void ModelDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(ModelDataItem, MODEL_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr += MODEL_FIELD_NAME;
+        valueStr += ": ";
+        valueStr += d->mModel;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void ManufacturerDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(ManufacturerDataItem, MANUFACTURER_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr += MANUFACTURER_FIELD_NAME;
+        valueStr += ": ";
+        valueStr += d->mManufacturer;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void WifiSupplicantStatusDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(WifiSupplicantStatusDataItem,
+                WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID);
+        valueStr += "Attach state: ";
+        char t[50];
+        memset (t, '\0', 50);
+        snprintf (t, 50, "%d", d->mState);
+        valueStr += t;
+
+        valueStr += ", Mac address valid: ";
+        valueStr += (d->mApMacAddressValid) ? ("true") : ("false");
+
+        valueStr += ", AP MAC address: ";
+        memset (t, '\0', 50);
+        snprintf(t, 50, "[%02x:%02x:%02x:%02x:%02x:%02x]", d->mApMacAddress[0], d->mApMacAddress[1],
+            d->mApMacAddress[2], d->mApMacAddress[3], d->mApMacAddress[4], d->mApMacAddress[5]);
+        valueStr += t;
+
+        valueStr += ", Wifi-Ap SSID Valid: ";
+        valueStr += (d->mWifiApSsidValid) ? ("true") : ("false");
+
+        valueStr += ", SSID: ";
+        valueStr += d->mWifiApSsid;
+
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void TacDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(TacDataItem, TAC_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr += TAC_FIELD_NAME;
+        valueStr += ": ";
+        valueStr += d->mValue;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void MccmncDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(MccmncDataItem, MCCMNC_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr += MCCMNC_FIELD_NAME;
+        valueStr += ": ";
+        valueStr += d->mValue;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void BtLeDeviceScanDetailsDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(BtLeDeviceScanDetailsDataItem, BTLE_SCAN_DATA_ITEM_ID);
+        valueStr.clear ();
+        valueStr += BTLESCANDETAILS_FIELD_VALID;
+        valueStr += ": ";
+        valueStr += d->mValidSrnData;
+        valueStr += ", ";
+
+        valueStr += BTLESCANDETAILS_FIELD_RSSI;
+        valueStr += ": ";
+        valueStr += d->mApSrnRssi;
+        valueStr += ", ";
+
+        char t[10];
+        memset (t, '\0', 10);
+        valueStr += BTLESCANDETAILS_FIELD_MAC;
+        valueStr += ": ";
+        snprintf(t, 10, "[%02x:%02x:%02x:%02x:%02x:%02x]", d->mApSrnMacAddress[0],
+                d->mApSrnMacAddress[1], d->mApSrnMacAddress[2], d->mApSrnMacAddress[3],
+                d->mApSrnMacAddress[4], d->mApSrnMacAddress[5]);
+        valueStr += t;
+        valueStr += ", ";
+
+        valueStr += BTLESCANDETAILS_FIELD_SCANREQ;
+        valueStr += ": ";
+        valueStr += d->mApSrnTimestamp;
+        valueStr += ", ";
+
+        valueStr += BTLESCANDETAILS_FIELD_SCANSTART;
+        valueStr += ": ";
+        valueStr += d->mRequestTimestamp;
+        valueStr += ", ";
+
+        valueStr += BTLESCANDETAILS_FIELD_SCANRECV;
+        valueStr += ": ";
+        valueStr += d->mReceiveTimestamp;
+        valueStr += ", ";
+
+        valueStr += BTLESCANDETAILS_FIELD_SCANERROR;
+        valueStr += ": ";
+        valueStr += d->mErrorCause;
+        valueStr += ", ";
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+void BtDeviceScanDetailsDataItem::stringify(string& valueStr) {
+    int32_t result = 0;
+    ENTRY_LOG();
+    do {
+        STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(BtDeviceScanDetailsDataItem, BT_SCAN_DATA_ITEM_ID);
+        valueStr.clear ();
+
+        valueStr += BTSCANDETAILS_FIELD_VALID;
+        valueStr += ": ";
+        valueStr += d->mValidSrnData;
+        valueStr += ", ";
+
+        valueStr += BTSCANDETAILS_FIELD_RSSI;
+        valueStr += ": ";
+        valueStr += d->mApSrnRssi;
+        valueStr += ", ";
+
+        char t[10];
+        memset (t, '\0', 10);
+        valueStr += BTSCANDETAILS_FIELD_MAC;
+        valueStr += ": ";
+        snprintf(t, 10, "[%02x:%02x:%02x:%02x:%02x:%02x]", d->mApSrnMacAddress[0],
+                d->mApSrnMacAddress[1], d->mApSrnMacAddress[2], d->mApSrnMacAddress[3],
+                d->mApSrnMacAddress[4], d->mApSrnMacAddress[5]);
+        valueStr += t;
+        valueStr += ", ";
+
+        valueStr += BTSCANDETAILS_FIELD_SCANREQ;
+        valueStr += ": ";
+        valueStr += d->mApSrnTimestamp;
+        valueStr += ", ";
+
+        valueStr += BTSCANDETAILS_FIELD_SCANSTART;
+        valueStr += ": ";
+        valueStr += d->mRequestTimestamp;
+        valueStr += ", ";
+
+        valueStr += BTSCANDETAILS_FIELD_SCANRECV;
+        valueStr += ": ";
+        valueStr += d->mReceiveTimestamp;
+        valueStr += ", ";
+
+        valueStr += BTSCANDETAILS_FIELD_SCANERROR;
+        valueStr += ": ";
+        valueStr += d->mErrorCause;
+        valueStr += ", ";
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+}
+
+// copy
+int32_t AirplaneModeDataItem::copyFrom(IDataItemCore* src) {
+   int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(AirplaneModeDataItem,  AIRPLANEMODE_DATA_ITEM_ID);
+        if (s->mMode == d->mMode) { result = 0; break; }
+         s->mMode = d->mMode;
+         result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t ENHDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(ENHDataItem,  ENH_DATA_ITEM_ID);
+        if (s->mEnhFields == d->mEnhFields) { result = true; break; }
+        switch (d->mAction) {
+            case SET:
+                s->mEnhFields |= (1 << d->mFieldUpdate);
+                break;
+            case CLEAR:
+                s->mEnhFields &= ~(1 << d->mFieldUpdate);
+                break;
+            default:
+                break;
+        }
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t GPSStateDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(GPSStateDataItem,  GPSSTATE_DATA_ITEM_ID);
+        if (s->mEnabled == d->mEnabled) { result = 0; break; }
+        s->mEnabled = d->mEnabled;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+ }
+int32_t NLPStatusDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(NLPStatusDataItem, NLPSTATUS_DATA_ITEM_ID);
+        if (s->mEnabled == d->mEnabled) { result = 0; break; }
+         s->mEnabled = d->mEnabled;
+         result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t WifiHardwareStateDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(WifiHardwareStateDataItem, WIFIHARDWARESTATE_DATA_ITEM_ID);
+        if (s->mEnabled == d->mEnabled) { result = 0; break; }
+        s->mEnabled = d->mEnabled;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t ScreenStateDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(ScreenStateDataItem, SCREEN_STATE_DATA_ITEM_ID);
+        if (s->mState == d->mState) { result = 0; break; }
+        s->mState = d->mState;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t PowerConnectStateDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(PowerConnectStateDataItem,
+                POWER_CONNECTED_STATE_DATA_ITEM_ID);
+        if (s->mState == d->mState) { result = 0; break; }
+        s->mState = d->mState;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t BatteryLevelDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(BatteryLevelDataItem, BATTERY_LEVEL_DATA_ITEM_ID);
+        if (s->mBatteryPct == d->mBatteryPct) { result = 0; break; }
+        s->mBatteryPct = d->mBatteryPct;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t TimeZoneChangeDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(TimeZoneChangeDataItem, TIMEZONE_CHANGE_DATA_ITEM_ID);
+        if (s->mCurrTimeMillis == d->mCurrTimeMillis &&
+           s->mRawOffsetTZ == d->mRawOffsetTZ &&
+           s->mDstOffsetTZ == d->mDstOffsetTZ) {
+            result = 0;
+            break;
+        }
+        s->mCurrTimeMillis = d->mCurrTimeMillis;
+        s->mRawOffsetTZ = d->mRawOffsetTZ;
+        s->mDstOffsetTZ = d->mDstOffsetTZ;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t TimeChangeDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(TimeChangeDataItem, TIME_CHANGE_DATA_ITEM_ID);
+        if (s->mCurrTimeMillis == d->mCurrTimeMillis &&
+           s->mRawOffsetTZ == d->mRawOffsetTZ &&
+           s->mDstOffsetTZ == d->mDstOffsetTZ) {
+            result = 0;
+            break;
+        }
+        s->mCurrTimeMillis = d->mCurrTimeMillis;
+        s->mRawOffsetTZ = d->mRawOffsetTZ;
+        s->mDstOffsetTZ = d->mDstOffsetTZ;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t ShutdownStateDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(ShutdownStateDataItem, SHUTDOWN_STATE_DATA_ITEM_ID);
+        if (s->mState == d->mState) { result = 0; break; }
+        s->mState = d->mState;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t AssistedGpsDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(AssistedGpsDataItem, ASSISTED_GPS_DATA_ITEM_ID);
+        if (s->mEnabled == d->mEnabled) { result = 0; break; }
+        s->mEnabled = d->mEnabled;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t NetworkInfoDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(NetworkInfoDataItem, NETWORKINFO_DATA_ITEM_ID);
+        NetworkType type = ((NetworkInfoDataItem*)d)->getType();
+        if ( (s->mAllTypes == d->mAllTypes) &&
+            (s->getType() == type) && (0 == s->mTypeName.compare(d->mTypeName)) &&
+            (0 == s->mSubTypeName.compare(d->mSubTypeName)) &&
+            (s->mAvailable == d->mAvailable) &&
+            (s->mConnected == d->mConnected) &&
+            (s->mRoaming == d->mRoaming) &&
+            (memcmp(s->mAllNetworkHandles, d->mAllNetworkHandles,
+                    sizeof(s->mAllNetworkHandles)) == 0) &&
+            (s->mNetworkHandle == d->mNetworkHandle) ) {
+            result = 0;
+            break;
+        }
+
+        s->mAllTypes = (d->mAllTypes == 0) ? typeToAllTypes(type) : d->mAllTypes;
+        if (s->getType() != type) { s->setType(type);}
+        if (0 != s->mTypeName.compare(d->mTypeName)) { s->mTypeName = d->mTypeName;}
+        if (0 != s->mSubTypeName.compare(d->mSubTypeName)) {s->mSubTypeName = d->mSubTypeName;}
+        if (s->mAvailable != d->mAvailable) {s->mAvailable = d->mAvailable;}
+        if (s->mConnected != d->mConnected) {s->mConnected = d->mConnected;}
+        if (s->mRoaming != d->mRoaming) {s->mRoaming = d->mRoaming;}
+        if (memcmp(s->mAllNetworkHandles, d->mAllNetworkHandles,
+                sizeof(s->mAllNetworkHandles)) != 0) {
+            memcpy(static_cast<void*>(s->mAllNetworkHandles),
+                    static_cast<void *>(d->mAllNetworkHandles), sizeof(s->mAllNetworkHandles));
+        }
+        if (s->mNetworkHandle != d->mNetworkHandle) {s->mNetworkHandle = d->mNetworkHandle;}
+
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t ServiceStatusDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(ServiceStatusDataItem, SERVICESTATUS_DATA_ITEM_ID);
+        if (s->mServiceState == d->mServiceState) { result = 0; break; }
+        s->mServiceState = d->mServiceState;
+        result = 0;
+    } while (0);
+    EXIT_LOG("%d", result);
+    return result;
+}
+int32_t ModelDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(ModelDataItem, MODEL_DATA_ITEM_ID);
+        if (0 == s->mModel.compare(d->mModel)) { result = 0; break; }
+        s->mModel = d->mModel;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t ManufacturerDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(ManufacturerDataItem, MANUFACTURER_DATA_ITEM_ID);
+        if (0 == s->mManufacturer.compare(d->mManufacturer)) { result = 0; break; }
+        s->mManufacturer = d->mManufacturer;
+        result = 0;
+    } while (0);
+    EXIT_LOG("%d", result);
+    return result;
+}
+int32_t WifiSupplicantStatusDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(WifiSupplicantStatusDataItem,
+                WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID);
+        if ( (s->mState == d->mState) &&
+            (s->mApMacAddressValid == d->mApMacAddressValid) &&
+            (s->mWifiApSsidValid == d->mWifiApSsidValid)) {
+
+            // compare mac address
+            if (memcmp(s->mApMacAddress, d->mApMacAddress, sizeof(s->mApMacAddress)) == 0) {
+
+                // compare ssid
+                if (s->mWifiApSsid.compare(d->mWifiApSsid) == 0) {
+                    result = 0;
+                    break;
+                }
+            }
+        }
+
+        if (s->mState != d->mState) { s->mState = d->mState;}
+        if (s->mApMacAddressValid != d->mApMacAddressValid) {
+            s->mApMacAddressValid = d->mApMacAddressValid;
+        }
+        if (s->mWifiApSsidValid != d->mWifiApSsidValid) {s->mWifiApSsidValid = d->mWifiApSsidValid;}
+        if (memcmp(s->mApMacAddress, d->mApMacAddress, sizeof(s->mApMacAddress)) != 0) {
+            memcpy(static_cast<void*>(s->mApMacAddress), static_cast<void *>(d->mApMacAddress),
+                    sizeof(s->mApMacAddress));
+        }
+        if (s->mWifiApSsid.compare(d->mWifiApSsid) != 0) {
+            s->mWifiApSsid = d->mWifiApSsid;
+        }
+
+        result = 0;
+    } while (0);
+
+    EXIT_LOG_WITH_ERROR("%d", result);
+    return result;
+}
+int32_t TacDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(TacDataItem, TAC_DATA_ITEM_ID);
+        if (0 == s->mValue.compare(d->mValue)) { result = 0; break; }
+        s->mValue = d->mValue;
+        result = 0;
+    } while (0);
+    EXIT_LOG("%d", result);
+    return result;
+}
+int32_t MccmncDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(MccmncDataItem, MCCMNC_DATA_ITEM_ID);
+        if (0 == s->mValue.compare(d->mValue)) { result = 0; break; }
+        s->mValue= d->mValue;
+        result = 0;
+    } while (0);
+    EXIT_LOG("%d", result);
+    return result;
+}
+int32_t BtLeDeviceScanDetailsDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(BtLeDeviceScanDetailsDataItem, BTLE_SCAN_DATA_ITEM_ID);
+
+        if (s->mValidSrnData != d->mValidSrnData) { s->mValidSrnData = d->mValidSrnData;}
+        if (s->mApSrnRssi != d->mApSrnRssi) { s->mApSrnRssi = d->mApSrnRssi;}
+        if (memcmp(s->mApSrnMacAddress, d->mApSrnMacAddress, sizeof(s->mApSrnMacAddress)) != 0) {
+            memcpy(static_cast<void*>(s->mApSrnMacAddress), static_cast<void*>(d->mApSrnMacAddress),
+                    sizeof(s->mApSrnMacAddress));
+        }
+        if (s->mApSrnTimestamp != d->mApSrnTimestamp) {s->mApSrnTimestamp = d->mApSrnTimestamp;}
+        if (s->mRequestTimestamp != d->mRequestTimestamp) {
+            s->mRequestTimestamp = d->mRequestTimestamp;
+        }
+        if (s->mReceiveTimestamp != d->mReceiveTimestamp) {
+            s->mReceiveTimestamp = d->mReceiveTimestamp;
+        }
+        if (s->mErrorCause != d->mErrorCause) {s->mErrorCause = d->mErrorCause;}
+        result = 0;
+    } while (0);
+    EXIT_LOG("%d", result);
+    return result;
+}
+int32_t BtDeviceScanDetailsDataItem::copyFrom(IDataItemCore* src) {
+    int32_t result = -1;
+    ENTRY_LOG();
+    do {
+        COPIER_ERROR_CHECK_AND_DOWN_CAST(BtDeviceScanDetailsDataItem, BT_SCAN_DATA_ITEM_ID);
+
+        if (s->mValidSrnData != d->mValidSrnData) { s->mValidSrnData = d->mValidSrnData;}
+        if (s->mApSrnRssi != d->mApSrnRssi) { s->mApSrnRssi = d->mApSrnRssi;}
+        if (memcmp(s->mApSrnMacAddress, d->mApSrnMacAddress, sizeof(s->mApSrnMacAddress)) != 0) {
+            memcpy(static_cast<void*>(s->mApSrnMacAddress), static_cast<void*>(d->mApSrnMacAddress),
+                    sizeof(s->mApSrnMacAddress));
+        }
+        if (s->mApSrnTimestamp != d->mApSrnTimestamp) {s->mApSrnTimestamp = d->mApSrnTimestamp;}
+        if (s->mRequestTimestamp != d->mRequestTimestamp) {
+            s->mRequestTimestamp = d->mRequestTimestamp;
+        }
+        if (s->mReceiveTimestamp != d->mReceiveTimestamp) {
+            s->mReceiveTimestamp = d->mReceiveTimestamp;
+        }
+        if (s->mErrorCause != d->mErrorCause) {s->mErrorCause = d->mErrorCause;}
+        result = 0;
+    } while (0);
+    EXIT_LOG("%d", result);
+    return result;
+}
+} //namespace loc_core
diff --git a/gps/core/data-items/DataItemConcreteTypes.h b/gps/core/data-items/DataItemConcreteTypes.h
new file mode 100644
index 0000000..c92ae54
--- /dev/null
+++ b/gps/core/data-items/DataItemConcreteTypes.h
@@ -0,0 +1,634 @@
+/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+Changes from Qualcomm Innovation Center are provided under the following license:
+Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+SPDX-License-Identifier: BSD-3-Clause-Clear
+*/
+
+#ifndef DATAITEM_CONCRETETYPES_H
+#define DATAITEM_CONCRETETYPES_H
+
+#include <string>
+#include <cstring>
+#include <sstream>
+#include <DataItemId.h>
+#include <IDataItemCore.h>
+#include <gps_extended_c.h>
+#include <inttypes.h>
+
+#define MAC_ADDRESS_LENGTH    6
+// MAC address length in bytes
+// QMI_LOC_SRN_MAC_ADDR_LENGTH_V02
+#define SRN_MAC_ADDRESS_LENGTH    6
+#define WIFI_SUPPLICANT_DEFAULT_STATE    0
+
+#define TIME_DEFAULT_CURRTIME 0
+#define TIMEZONE_DEFAULT_RAWOFFSET 0
+#define TIMEZONE_DEFAULT_DSTOFFSET 0
+
+#define NETWORKINFO_DEFAULT_TYPE 300
+#define SERVICESTATUS_DEFAULT_STATE 3 /// OOO
+
+#define BATTERY_PCT_DEFAULT 50
+
+#define STRINGIFY_ERROR_CHECK_AND_DOWN_CAST(T, ID) \
+if (getId() != ID) { result = 1; break; } \
+T * d = static_cast<T *>(this);
+
+// macro for copier
+#define COPIER_ERROR_CHECK_AND_DOWN_CAST(T, ID) \
+   if (src == NULL) { result = 1; break; } \
+   if (getId() != src->getId()) { result = 2; break; } \
+   if (getId() != ID) { result = 3; break; } \
+   T * s = static_cast<T *>(this); \
+   T * d = static_cast<T *>(src);
+
+
+static constexpr char sDelimit = ':';
+
+namespace loc_core {
+using namespace std;
+
+enum NetworkType {
+    TYPE_MOBILE = 0,
+    TYPE_WIFI,
+    TYPE_ETHERNET,
+    TYPE_BLUETOOTH,
+    TYPE_MMS,
+    TYPE_SUPL,
+    TYPE_DUN,
+    TYPE_HIPRI,
+    TYPE_WIMAX,
+    TYPE_PROXY,
+    TYPE_UNKNOWN,
+};
+
+typedef struct NetworkInfoType {
+    // Unique network handle ID
+    uint64_t networkHandle;
+    // Type of network for corresponding network handle
+    NetworkType networkType;
+    NetworkInfoType() : networkHandle(NETWORK_HANDLE_UNKNOWN), networkType(TYPE_UNKNOWN) {}
+    NetworkInfoType(string strObj) {
+        size_t posDelimit = strObj.find(sDelimit);
+
+        if ( posDelimit != string::npos) {
+            int32_t type = TYPE_UNKNOWN;
+            string handleStr = strObj.substr(0, posDelimit);
+            string typeStr = strObj.substr(posDelimit + 1, strObj.length() - posDelimit - 1);
+            stringstream(handleStr) >> networkHandle;
+            stringstream(typeStr) >> type;
+            networkType = (NetworkType) type;
+        } else {
+            networkHandle = NETWORK_HANDLE_UNKNOWN;
+            networkType = TYPE_UNKNOWN;
+        }
+    }
+    bool operator== (const NetworkInfoType& other) {
+        return ((networkHandle == other.networkHandle) && (networkType == other.networkType));
+    }
+    string toString() {
+        string valueStr;
+        valueStr.clear ();
+        char nethandle [32];
+        memset (nethandle, 0, 32);
+        snprintf(nethandle, sizeof(nethandle), "%" PRIu64, networkHandle);
+        valueStr += string(nethandle);
+        valueStr += sDelimit;
+        char type [12];
+        memset (type, 0, 12);
+        snprintf (type, 12, "%u", networkType);
+        valueStr += string (type);
+        return valueStr;
+    }
+} NetworkInfoType;
+
+
+class AirplaneModeDataItem: public IDataItemCore  {
+public:
+    AirplaneModeDataItem(IDataItemCore* di):
+            AirplaneModeDataItem(((AirplaneModeDataItem*)di)->mMode) {}
+    AirplaneModeDataItem(bool mode = false):
+        mMode(mode) {mId = AIRPLANEMODE_DATA_ITEM_ID;}
+    virtual ~AirplaneModeDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mMode;
+
+};
+
+class ENHDataItem: public IDataItemCore {
+public:
+    enum Fields { FIELD_CONSENT, FIELD_REGION, FIELD_MAX };
+    enum Actions { NO_OP, SET, CLEAR };
+    ENHDataItem(bool enabled = false, Fields updateBit = FIELD_MAX) :
+            mEnhFields(0), mFieldUpdate(updateBit) {
+        mId = ENH_DATA_ITEM_ID;
+        setAction(enabled ? SET : CLEAR);
+    }
+    virtual ~ENHDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+    inline bool isEnabled() const {
+        uint8_t combinedBits = (1 << FIELD_MAX) - 1;
+        return (combinedBits == (mEnhFields & combinedBits));
+    }
+    void setAction(Actions action = NO_OP) {
+        mAction = action;
+        if (NO_OP != mAction) {
+            updateFields();
+        }
+    }
+    void updateFields() {
+        if (FIELD_MAX > mFieldUpdate) {
+            switch (mAction) {
+                case SET:
+                    mEnhFields |= (1 << mFieldUpdate);
+                    break;
+                case CLEAR:
+                    mEnhFields &= ~(1 << mFieldUpdate);
+                    break;
+                case NO_OP:
+                default:
+                    break;
+            }
+        }
+    }
+    // Data members
+    uint32_t mEnhFields;
+private:
+    Actions mAction;
+    Fields mFieldUpdate;
+};
+
+class GPSStateDataItem: public IDataItemCore {
+public:
+    GPSStateDataItem(bool enabled = false) :
+        mEnabled(enabled) {mId = GPSSTATE_DATA_ITEM_ID;}
+    virtual ~GPSStateDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mEnabled;
+};
+
+class NLPStatusDataItem: public IDataItemCore {
+public:
+    NLPStatusDataItem(bool enabled = false) :
+        mEnabled(enabled) {mId = NLPSTATUS_DATA_ITEM_ID;}
+    virtual ~NLPStatusDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mEnabled;
+};
+
+class WifiHardwareStateDataItem: public IDataItemCore {
+public:
+    WifiHardwareStateDataItem(bool enabled = false) :
+        mEnabled(enabled) {mId = WIFIHARDWARESTATE_DATA_ITEM_ID;}
+    virtual ~WifiHardwareStateDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mEnabled;
+};
+
+class ScreenStateDataItem: public IDataItemCore {
+public:
+    ScreenStateDataItem(bool state = false) :
+        mState(state) {mId = SCREEN_STATE_DATA_ITEM_ID;}
+    virtual ~ScreenStateDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mState;
+};
+
+class PowerConnectStateDataItem: public IDataItemCore {
+public:
+    PowerConnectStateDataItem(bool state = false) :
+        mState(state) {mId = POWER_CONNECTED_STATE_DATA_ITEM_ID;}
+    virtual ~PowerConnectStateDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mState;
+};
+
+class TimeZoneChangeDataItem: public IDataItemCore {
+public:
+    TimeZoneChangeDataItem(int64_t currTimeMillis = TIME_DEFAULT_CURRTIME,
+            int32_t rawOffset = TIMEZONE_DEFAULT_RAWOFFSET,
+            int32_t dstOffset = TIMEZONE_DEFAULT_DSTOFFSET) :
+        mCurrTimeMillis (currTimeMillis),
+        mRawOffsetTZ (rawOffset),
+        mDstOffsetTZ (dstOffset) {mId = TIMEZONE_CHANGE_DATA_ITEM_ID;}
+    virtual ~TimeZoneChangeDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    int64_t mCurrTimeMillis;
+    int32_t mRawOffsetTZ;
+    int32_t mDstOffsetTZ;
+};
+
+class TimeChangeDataItem: public IDataItemCore {
+public:
+    TimeChangeDataItem(int64_t currTimeMillis = TIME_DEFAULT_CURRTIME,
+            int32_t rawOffset = TIMEZONE_DEFAULT_RAWOFFSET,
+            int32_t dstOffset = TIMEZONE_DEFAULT_DSTOFFSET) :
+        mCurrTimeMillis (currTimeMillis),
+        mRawOffsetTZ (rawOffset),
+        mDstOffsetTZ (dstOffset) {mId = TIME_CHANGE_DATA_ITEM_ID;}
+    virtual ~TimeChangeDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    int64_t mCurrTimeMillis;
+    int32_t mRawOffsetTZ;
+    int32_t mDstOffsetTZ;
+};
+
+class ShutdownStateDataItem: public IDataItemCore {
+public:
+    ShutdownStateDataItem(bool state = false) :
+        mState (state) {mId = SHUTDOWN_STATE_DATA_ITEM_ID;}
+    virtual ~ShutdownStateDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mState;
+};
+
+class AssistedGpsDataItem: public IDataItemCore {
+public:
+    AssistedGpsDataItem(bool enabled = false) :
+        mEnabled(enabled) {mId = ASSISTED_GPS_DATA_ITEM_ID;}
+    virtual ~AssistedGpsDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    bool mEnabled;
+};
+
+class NetworkInfoDataItem: public IDataItemCore {
+public:
+    NetworkInfoDataItem(
+            int32_t type = NETWORKINFO_DEFAULT_TYPE,
+            std::string typeName = "",
+            std::string subTypeName = "",
+            bool available = false,
+            bool connected = false,
+            bool roaming = false,
+            uint64_t networkHandle = NETWORK_HANDLE_UNKNOWN, string apn = ""):
+        NetworkInfoDataItem(getNormalizedType(type), type, typeName, subTypeName, available,
+        connected, roaming, networkHandle, "") {}
+    NetworkInfoDataItem(NetworkType initialType, int32_t type, string typeName,
+            string subTypeName, bool available, bool connected, bool roaming,
+            uint64_t networkHandle, string apn):
+            mAllTypes(typeToAllTypes(initialType)),
+            mType(type),
+            mTypeName(typeName),
+            mSubTypeName(subTypeName),
+            mAvailable(available),
+            mConnected(connected),
+            mRoaming(roaming),
+            mNetworkHandle(networkHandle), mApn(apn) {
+                mId = NETWORKINFO_DATA_ITEM_ID;
+                mAllNetworkHandles[0].networkHandle = networkHandle;
+                mAllNetworkHandles[0].networkType = initialType;
+            }
+    virtual ~NetworkInfoDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+    inline uint64_t getAllTypes() { return mAllTypes; }
+    inline NetworkInfoType* getNetworkHandle() {
+        return &mAllNetworkHandles[0];
+    }
+    inline virtual NetworkType getType(void) const {
+        return getNormalizedType(mType);
+    }
+    inline static NetworkType getNormalizedType(int32_t type) {
+        NetworkType typeout = TYPE_UNKNOWN;
+        switch (type) {
+            case 100:
+                typeout = TYPE_WIFI;
+                break;
+            case 101:
+                typeout = TYPE_ETHERNET;
+                break;
+            case 102:
+                typeout = TYPE_BLUETOOTH;
+                break;
+            case 201:
+                typeout = TYPE_MOBILE;
+                break;
+            case 202:
+                typeout = TYPE_DUN;
+                break;
+            case 203:
+                typeout = TYPE_HIPRI;
+                break;
+            case 204:
+                typeout = TYPE_MMS;
+                break;
+            case 205:
+                typeout = TYPE_SUPL;
+                break;
+            case 220:
+                typeout = TYPE_WIMAX;
+                break;
+            case 300:
+            default:
+                typeout = TYPE_UNKNOWN;
+                break;
+        }
+        return typeout;
+   }
+    // Data members
+    uint64_t mAllTypes;
+    int32_t mType;
+    string mTypeName;
+    string mSubTypeName;
+    bool mAvailable;
+    bool mConnected;
+    bool mRoaming;
+    NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES];
+    uint64_t mNetworkHandle;
+    string mApn;
+protected:
+    inline uint64_t typeToAllTypes(NetworkType type) {
+        return (type >= TYPE_UNKNOWN || type < TYPE_MOBILE) ?  0 : (1<<type);
+    }
+private:
+    inline void setType(NetworkType type) {
+        switch (type) {
+            case TYPE_WIFI:
+                mType = 100;
+                break;
+            case TYPE_ETHERNET:
+                mType = 101;
+                break;
+            case TYPE_BLUETOOTH:
+                mType = 102;
+                break;
+            case TYPE_MOBILE:
+                mType = 201;
+                break;
+            case TYPE_DUN:
+                mType = 202;
+                break;
+            case TYPE_HIPRI:
+                mType = 203;
+                break;
+            case TYPE_MMS:
+                mType = 204;
+                break;
+            case TYPE_SUPL:
+                mType = 205;
+                break;
+            case TYPE_WIMAX:
+                mType = 220;
+                break;
+            default:
+                mType = 300;
+                break;
+        }
+    }
+};
+
+class ServiceStatusDataItem: public IDataItemCore {
+public:
+    ServiceStatusDataItem(int32_t serviceState = SERVICESTATUS_DEFAULT_STATE) :
+        mServiceState (serviceState) {mId = SERVICESTATUS_DATA_ITEM_ID;}
+    virtual ~ServiceStatusDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    int32_t mServiceState;
+};
+
+class ModelDataItem: public IDataItemCore {
+public:
+    ModelDataItem(const string & name = "") :
+        mModel (name) {mId = MODEL_DATA_ITEM_ID;}
+    virtual ~ModelDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    string mModel;
+};
+
+class ManufacturerDataItem: public IDataItemCore {
+public:
+    ManufacturerDataItem(const string & name = "") :
+        mManufacturer (name) {mId = MANUFACTURER_DATA_ITEM_ID;}
+    virtual ~ManufacturerDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    string mManufacturer;
+};
+
+class RilServiceInfoDataItem : public IDataItemCore {
+public:
+    inline RilServiceInfoDataItem() :
+            mData(nullptr) {mId = RILSERVICEINFO_DATA_ITEM_ID;}
+    inline virtual ~RilServiceInfoDataItem() { if (nullptr != mData) free(mData); }
+    virtual void stringify(string& /*valueStr*/) {}
+    virtual int32_t copyFrom(IDataItemCore* src) {
+        memcpy(mData,  ((RilServiceInfoDataItem*)src)->mData, mLength);
+        return 0;
+    }
+    inline RilServiceInfoDataItem(const RilServiceInfoDataItem& peer) :
+            RilServiceInfoDataItem() {
+        mLength = peer.mLength;
+        mData = malloc(mLength);
+        memcpy(mData,  peer.mData, mLength);
+        peer.setPeerData(*this);
+    }
+    inline virtual bool operator==(const RilServiceInfoDataItem& other) const {
+        return other.mData == mData;
+    }
+    inline virtual void setPeerData(RilServiceInfoDataItem& /*peer*/) const {}
+    void* mData;
+    int mLength;
+};
+
+class RilCellInfoDataItem : public IDataItemCore {
+public:
+    inline RilCellInfoDataItem() :
+            mData(nullptr) {mId = RILCELLINFO_DATA_ITEM_ID;}
+    inline virtual ~RilCellInfoDataItem() { if (nullptr != mData) free(mData); }
+    virtual void stringify(string& /*valueStr*/) {}
+    virtual int32_t copyFrom(IDataItemCore* src) {
+        memcpy(mData,  ((RilCellInfoDataItem*)src)->mData, mLength);
+        return 0;
+    }
+    inline RilCellInfoDataItem(const RilCellInfoDataItem& peer) :
+            RilCellInfoDataItem() {
+        mLength = peer.mLength;
+        mData = malloc(mLength);
+        memcpy(mData,  peer.mData, mLength);
+        peer.setPeerData(*this);
+    }
+    inline virtual bool operator==(const RilCellInfoDataItem& other) const {
+        return other.mData == mData;
+    }
+    inline virtual void setPeerData(RilCellInfoDataItem& /*peer*/) const {}
+    void* mData;
+    int mLength;
+};
+
+class WifiSupplicantStatusDataItem: public IDataItemCore {
+public:
+    WifiSupplicantStatusDataItem() :
+        mState((WifiSupplicantState)WIFI_SUPPLICANT_DEFAULT_STATE),
+        mApMacAddressValid(false),
+        mWifiApSsidValid(false) {
+            mId = WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID;
+            memset (mApMacAddress, 0, sizeof (mApMacAddress));
+            mWifiApSsid.clear();
+        }
+    virtual ~WifiSupplicantStatusDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+    // Data members
+    typedef enum WifiSupplicantState {
+        DISCONNECTED,
+        INTERFACE_DISABLED,
+        INACTIVE,
+        SCANNING,
+        AUTHENTICATING,
+        ASSOCIATING,
+        ASSOCIATED,
+        FOUR_WAY_HANDSHAKE,
+        GROUP_HANDSHAKE,
+        COMPLETED,
+        DORMANT,
+        UNINITIALIZED,
+        INVALID
+    } WifiSupplicantState;
+    /* Represents whether access point attach state*/
+    WifiSupplicantState mState;
+    /* Represents info on whether ap mac address is valid */
+    bool mApMacAddressValid;
+    /* Represents mac address of the wifi access point*/
+    uint8_t mApMacAddress[MAC_ADDRESS_LENGTH];
+    /* Represents info on whether ap SSID is valid */
+    bool mWifiApSsidValid;
+    /* Represents Wifi SSID string*/
+    string mWifiApSsid;
+};
+
+class TacDataItem: public IDataItemCore {
+public:
+    TacDataItem(const string & name = "") :
+        mValue (name) {mId = TAC_DATA_ITEM_ID;}
+    virtual ~TacDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    string mValue;
+};
+
+class MccmncDataItem: public IDataItemCore {
+public:
+    MccmncDataItem(const string & name = "") :
+        mValue(name) {mId = MCCMNC_DATA_ITEM_ID;}
+    virtual ~MccmncDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    string mValue;
+};
+
+class SrnDeviceScanDetailsDataItem: public IDataItemCore {
+public:
+    SrnDeviceScanDetailsDataItem(DataItemId Id) :
+        mValidSrnData(false),
+        mApSrnRssi(-1),
+        mApSrnTimestamp(0),
+        mRequestTimestamp(0),
+        mReceiveTimestamp(0),
+       mErrorCause(-1) {mId = Id;}
+    virtual ~SrnDeviceScanDetailsDataItem() {}
+    // Data members common to all SRN tech types
+    /* Represents info on whether SRN data is valid (no error)*/
+    bool mValidSrnData;
+    /* SRN device RSSI reported */
+    int32_t mApSrnRssi;
+    /* MAC adress of SRN device */
+    uint8_t mApSrnMacAddress[SRN_MAC_ADDRESS_LENGTH];
+    /* UTC timestamp at which the scan was requested.for this SRN device*/
+    int64_t mApSrnTimestamp;
+    /* UTC timestamp at which the scan was started. */
+    int64_t mRequestTimestamp;
+    /* UTC timestamp at which the scan was received.*/
+    int64_t mReceiveTimestamp;
+    /* Reason for the error/failure if SRN details are not valid */
+    int32_t mErrorCause;
+};
+
+class BtDeviceScanDetailsDataItem: public SrnDeviceScanDetailsDataItem {
+public:
+    BtDeviceScanDetailsDataItem() :
+        SrnDeviceScanDetailsDataItem(BT_SCAN_DATA_ITEM_ID) {}
+    virtual ~BtDeviceScanDetailsDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+};
+
+class BtLeDeviceScanDetailsDataItem: public SrnDeviceScanDetailsDataItem {
+public:
+    BtLeDeviceScanDetailsDataItem() :
+        SrnDeviceScanDetailsDataItem(BTLE_SCAN_DATA_ITEM_ID) {}
+    virtual ~BtLeDeviceScanDetailsDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+};
+
+class BatteryLevelDataItem: public IDataItemCore {
+public:
+    inline BatteryLevelDataItem(uint8_t batteryPct = BATTERY_PCT_DEFAULT) :
+            mBatteryPct(batteryPct) {mId = BATTERY_LEVEL_DATA_ITEM_ID;}
+    inline ~BatteryLevelDataItem() {}
+    virtual void stringify(string& /*valueStr*/) override;
+    virtual int32_t copyFrom(IDataItemCore* /*src*/) override;
+// Data members
+    uint8_t mBatteryPct;
+};
+
+} // namespace loc_core
+
+#endif //DATAITEM_CONCRETETYPES_H
diff --git a/gps/core/data-items/DataItemConcreteTypesBase.h b/gps/core/data-items/DataItemConcreteTypesBase.h
deleted file mode 100644
index 1ab1ecb..0000000
--- a/gps/core/data-items/DataItemConcreteTypesBase.h
+++ /dev/null
@@ -1,555 +0,0 @@
-/* Copyright (c) 2015-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 __DATAITEMCONCRETEBASETYPES__
-#define __DATAITEMCONCRETEBASETYPES__
-
-#include <string>
-#include <cstring>
-#include <sstream>
-#include <DataItemId.h>
-#include <IDataItemCore.h>
-#include <gps_extended_c.h>
-#include <inttypes.h>
-
-#define MAC_ADDRESS_LENGTH    6
-// MAC address length in bytes
-// QMI_LOC_SRN_MAC_ADDR_LENGTH_V02
-#define SRN_MAC_ADDRESS_LENGTH    6
-#define WIFI_SUPPLICANT_DEFAULT_STATE    0
-
-static constexpr char sDelimit = ':';
-
-namespace loc_core
-{
-using namespace std;
-
-enum NetworkType {
-    TYPE_MOBILE = 0,
-    TYPE_WIFI,
-    TYPE_ETHERNET,
-    TYPE_BLUETOOTH,
-    TYPE_MMS,
-    TYPE_SUPL,
-    TYPE_DUN,
-    TYPE_HIPRI,
-    TYPE_WIMAX,
-    TYPE_PROXY,
-    TYPE_UNKNOWN,
-};
-
-typedef struct NetworkInfoType
-{
-    // Unique network handle ID
-    uint64_t networkHandle;
-    // Type of network for corresponding network handle
-    NetworkType networkType;
-    NetworkInfoType() : networkHandle(NETWORK_HANDLE_UNKNOWN), networkType(TYPE_UNKNOWN) {}
-    NetworkInfoType(string strObj) {
-        size_t posDelimit = strObj.find(sDelimit);
-
-        if ( posDelimit != string::npos) {
-            int32_t type = TYPE_UNKNOWN;
-            string handleStr = strObj.substr(0, posDelimit);
-            string typeStr = strObj.substr(posDelimit + 1, strObj.length() - posDelimit - 1);
-            stringstream(handleStr) >> networkHandle;
-            stringstream(typeStr) >> type;
-            networkType = (NetworkType) type;
-        } else {
-            networkHandle = NETWORK_HANDLE_UNKNOWN;
-            networkType = TYPE_UNKNOWN;
-        }
-    }
-    bool operator== (const NetworkInfoType& other) {
-        return ((networkHandle == other.networkHandle) && (networkType == other.networkType));
-    }
-    string toString() {
-        string valueStr;
-        valueStr.clear ();
-        char nethandle [32];
-        memset (nethandle, 0, 32);
-        snprintf(nethandle, sizeof(nethandle), "%" PRIu64, networkHandle);
-        valueStr += string(nethandle);
-        valueStr += sDelimit;
-        char type [12];
-        memset (type, 0, 12);
-        snprintf (type, 12, "%u", networkType);
-        valueStr += string (type);
-        return valueStr;
-    }
-} NetworkInfoType;
-
-
-class AirplaneModeDataItemBase : public IDataItemCore  {
-public:
-    AirplaneModeDataItemBase(bool mode):
-        mMode(mode),
-        mId(AIRPLANEMODE_DATA_ITEM_ID) {}
-    virtual ~AirplaneModeDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mMode;
-
-protected:
-    DataItemId mId;
-};
-
-class ENHDataItemBase : public IDataItemCore {
-public:
-    ENHDataItemBase(bool enabled) :
-        mEnabled(enabled),
-        mId(ENH_DATA_ITEM_ID) {}
-    virtual ~ENHDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mEnabled;
-protected:
-    DataItemId mId;
-};
-
-class GPSStateDataItemBase : public IDataItemCore {
-public:
-    GPSStateDataItemBase(bool enabled) :
-        mEnabled(enabled),
-        mId(GPSSTATE_DATA_ITEM_ID) {}
-    virtual ~GPSStateDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mEnabled;
-protected:
-    DataItemId mId;
-};
-
-class NLPStatusDataItemBase : public IDataItemCore {
-public:
-    NLPStatusDataItemBase(bool enabled) :
-        mEnabled(enabled),
-        mId(NLPSTATUS_DATA_ITEM_ID) {}
-    virtual ~NLPStatusDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mEnabled;
-protected:
-    DataItemId mId;
-};
-
-class WifiHardwareStateDataItemBase : public IDataItemCore {
-public:
-    WifiHardwareStateDataItemBase(bool enabled) :
-        mEnabled(enabled),
-        mId(WIFIHARDWARESTATE_DATA_ITEM_ID) {}
-    virtual ~WifiHardwareStateDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mEnabled;
-protected:
-    DataItemId mId;
-};
-
-class ScreenStateDataItemBase : public IDataItemCore {
-public:
-    ScreenStateDataItemBase(bool state) :
-        mState(state),
-        mId(SCREEN_STATE_DATA_ITEM_ID) {}
-    virtual ~ScreenStateDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mState;
-protected:
-    DataItemId mId;
-};
-
-class PowerConnectStateDataItemBase : public IDataItemCore {
-public:
-    PowerConnectStateDataItemBase(bool state) :
-        mState(state),
-        mId(POWER_CONNECTED_STATE_DATA_ITEM_ID) {}
-    virtual ~PowerConnectStateDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mState;
-protected:
-    DataItemId mId;
-};
-
-class TimeZoneChangeDataItemBase : public IDataItemCore {
-public:
-    TimeZoneChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) :
-        mCurrTimeMillis (currTimeMillis),
-        mRawOffsetTZ (rawOffset),
-        mDstOffsetTZ (dstOffset),
-        mId(TIMEZONE_CHANGE_DATA_ITEM_ID) {}
-    virtual ~TimeZoneChangeDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    int64_t mCurrTimeMillis;
-    int32_t mRawOffsetTZ;
-    int32_t mDstOffsetTZ;
-protected:
-    DataItemId mId;
-};
-
-class TimeChangeDataItemBase : public IDataItemCore {
-public:
-    TimeChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) :
-        mCurrTimeMillis (currTimeMillis),
-        mRawOffsetTZ (rawOffset),
-        mDstOffsetTZ (dstOffset),
-        mId(TIME_CHANGE_DATA_ITEM_ID) {}
-    virtual ~TimeChangeDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    int64_t mCurrTimeMillis;
-    int32_t mRawOffsetTZ;
-    int32_t mDstOffsetTZ;
-protected:
-    DataItemId mId;
-};
-
-class ShutdownStateDataItemBase : public IDataItemCore {
-public:
-    ShutdownStateDataItemBase(bool state) :
-        mState (state),
-        mId(SHUTDOWN_STATE_DATA_ITEM_ID) {}
-    virtual ~ShutdownStateDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mState;
-protected:
-    DataItemId mId;
-};
-
-class AssistedGpsDataItemBase : public IDataItemCore {
-public:
-    AssistedGpsDataItemBase(bool enabled) :
-        mEnabled(enabled),
-        mId(ASSISTED_GPS_DATA_ITEM_ID) {}
-    virtual ~AssistedGpsDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    bool mEnabled;
-protected:
-    DataItemId mId;
-};
-
-class NetworkInfoDataItemBase : public IDataItemCore {
-public:
-    NetworkInfoDataItemBase(
-    NetworkType initialType, int32_t type, string typeName, string subTypeName,
-    bool available, bool connected, bool roaming, uint64_t networkHandle, string apn):
-            mAllTypes(typeToAllTypes(initialType)),
-            mType(type),
-            mTypeName(typeName),
-            mSubTypeName(subTypeName),
-            mAvailable(available),
-            mConnected(connected),
-            mRoaming(roaming),
-            mNetworkHandle(networkHandle),
-            mApn(apn), mId(NETWORKINFO_DATA_ITEM_ID) {
-                mAllNetworkHandles[0].networkHandle = networkHandle;
-                mAllNetworkHandles[0].networkType = initialType;
-            }
-    virtual ~NetworkInfoDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-    inline virtual NetworkType getType(void) const {
-        return (NetworkType)mType;
-    }
-    inline uint64_t getAllTypes() { return mAllTypes; }
-    inline NetworkInfoType* getNetworkHandle() {
-        return &mAllNetworkHandles[0];
-    }
-    // Data members
-    uint64_t mAllTypes;
-    int32_t mType;
-    string mTypeName;
-    string mSubTypeName;
-    bool mAvailable;
-    bool mConnected;
-    bool mRoaming;
-    NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES];
-    uint64_t mNetworkHandle;
-    string mApn;
-protected:
-    DataItemId mId;
-    inline uint64_t typeToAllTypes(NetworkType type) {
-        return (type >= TYPE_UNKNOWN || type < TYPE_MOBILE) ?  0 : (1<<type);
-    }
-};
-
-class ServiceStatusDataItemBase : public IDataItemCore {
-public:
-    ServiceStatusDataItemBase(int32_t serviceState) :
-        mServiceState (serviceState),
-        mId(SERVICESTATUS_DATA_ITEM_ID) {}
-    virtual ~ServiceStatusDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    int32_t mServiceState;
-protected:
-    DataItemId mId;
-};
-
-class ModelDataItemBase : public IDataItemCore {
-public:
-    ModelDataItemBase(const string & name) :
-        mModel (name),
-        mId(MODEL_DATA_ITEM_ID) {}
-    virtual ~ModelDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    string mModel;
-protected:
-    DataItemId mId;
-};
-
-class ManufacturerDataItemBase : public IDataItemCore {
-public:
-    ManufacturerDataItemBase(const string & name) :
-        mManufacturer (name),
-        mId(MANUFACTURER_DATA_ITEM_ID) {}
-    virtual ~ManufacturerDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    string mManufacturer;
-protected:
-    DataItemId mId;
-};
-
-class RilServiceInfoDataItemBase : public IDataItemCore {
-public:
-    inline RilServiceInfoDataItemBase() :
-            mData(nullptr), mId(RILSERVICEINFO_DATA_ITEM_ID) {}
-    inline virtual ~RilServiceInfoDataItemBase() { if (nullptr != mData) free(mData); }
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-    inline RilServiceInfoDataItemBase(const RilServiceInfoDataItemBase& peer) :
-            RilServiceInfoDataItemBase() {
-        peer.setPeerData(*this);
-    }
-    inline virtual bool operator==(const RilServiceInfoDataItemBase& other) const {
-        return other.mData == mData;
-    }
-    inline virtual void setPeerData(RilServiceInfoDataItemBase& /*peer*/) const {}
-    void* mData;
-protected:
-    DataItemId mId;
-};
-
-class RilCellInfoDataItemBase : public IDataItemCore {
-public:
-    inline RilCellInfoDataItemBase() :
-            mData(nullptr), mId(RILCELLINFO_DATA_ITEM_ID) {}
-    inline virtual ~RilCellInfoDataItemBase() { if (nullptr != mData) free(mData); }
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-    inline RilCellInfoDataItemBase(const RilCellInfoDataItemBase& peer) :
-            RilCellInfoDataItemBase() {
-        peer.setPeerData(*this);
-    }
-    inline virtual bool operator==(const RilCellInfoDataItemBase& other) const {
-        return other.mData == mData;
-    }
-    inline virtual void setPeerData(RilCellInfoDataItemBase& /*peer*/) const {}
-    void* mData;
-protected:
-    DataItemId mId;
-};
-
-class WifiSupplicantStatusDataItemBase : public IDataItemCore {
-public:
-    WifiSupplicantStatusDataItemBase() :
-        mState((WifiSupplicantState)WIFI_SUPPLICANT_DEFAULT_STATE),
-        mApMacAddressValid(false),
-        mWifiApSsidValid(false),
-        mId(WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID) {
-            memset (&mApMacAddress, 0, sizeof (mApMacAddress));
-            mWifiApSsid.clear();
-        }
-    virtual ~WifiSupplicantStatusDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-    // Data members
-    typedef enum WifiSupplicantState {
-        DISCONNECTED,
-        INTERFACE_DISABLED,
-        INACTIVE,
-        SCANNING,
-        AUTHENTICATING,
-        ASSOCIATING,
-        ASSOCIATED,
-        FOUR_WAY_HANDSHAKE,
-        GROUP_HANDSHAKE,
-        COMPLETED,
-        DORMANT,
-        UNINITIALIZED,
-        INVALID
-    } WifiSupplicantState;
-    /* Represents whether access point attach state*/
-    WifiSupplicantState mState;
-    /* Represents info on whether ap mac address is valid */
-    bool mApMacAddressValid;
-    /* Represents mac address of the wifi access point*/
-    uint8_t mApMacAddress[MAC_ADDRESS_LENGTH];
-    /* Represents info on whether ap SSID is valid */
-    bool mWifiApSsidValid;
-    /* Represents Wifi SSID string*/
-    string mWifiApSsid;
-protected:
-    DataItemId mId;
-};
-
-class TacDataItemBase : public IDataItemCore {
-public:
-    TacDataItemBase(const string & name) :
-        mValue (name),
-        mId(TAC_DATA_ITEM_ID) {}
-    virtual ~TacDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    string mValue;
-protected:
-    DataItemId mId;
-};
-
-class MccmncDataItemBase : public IDataItemCore {
-public:
-    MccmncDataItemBase(const string & name) :
-        mValue(name),
-        mId(MCCMNC_DATA_ITEM_ID) {}
-    virtual ~MccmncDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-// Data members
-    string mValue;
-protected:
-    DataItemId mId;
-};
-
-class SrnDeviceScanDetailsDataItemBase : public IDataItemCore {
-public:
-    SrnDeviceScanDetailsDataItemBase(DataItemId Id) :
-        mValidSrnData(false),
-        mApSrnRssi(-1),
-        mApSrnTimestamp(0),
-        mRequestTimestamp(0),
-        mReceiveTimestamp(0),
-        mErrorCause(-1),
-        mId(Id) {}
-    virtual ~SrnDeviceScanDetailsDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-    // Data members common to all SRN tech types
-    /* Represents info on whether SRN data is valid (no error)*/
-    bool mValidSrnData;
-    /* SRN device RSSI reported */
-    int32_t mApSrnRssi;
-    /* MAC adress of SRN device */
-    uint8_t mApSrnMacAddress[SRN_MAC_ADDRESS_LENGTH];
-    /* UTC timestamp at which the scan was requested.for this SRN device*/
-    int64_t mApSrnTimestamp;
-    /* UTC timestamp at which the scan was started. */
-    int64_t mRequestTimestamp;
-    /* UTC timestamp at which the scan was received.*/
-    int64_t mReceiveTimestamp;
-    /* Reason for the error/failure if SRN details are not valid */
-    int32_t mErrorCause;
-protected:
-    DataItemId mId;
-};
-
-class BtDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase {
-
-public:
-    BtDeviceScanDetailsDataItemBase() :
-        SrnDeviceScanDetailsDataItemBase(BT_SCAN_DATA_ITEM_ID) {}
-    virtual ~BtDeviceScanDetailsDataItemBase() {}
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-};
-
-class BtLeDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase {
-
-public:
-    BtLeDeviceScanDetailsDataItemBase() :
-        SrnDeviceScanDetailsDataItemBase(BTLE_SCAN_DATA_ITEM_ID) {}
-    virtual ~BtLeDeviceScanDetailsDataItemBase() {}
-    virtual void stringify(string& /*valueStr*/) {}
-    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
-};
-
-class BatteryLevelDataItemBase : public IDataItemCore {
-public:
-    inline BatteryLevelDataItemBase(uint8_t batteryPct) :
-            mBatteryPct(batteryPct), mId(BATTERY_LEVEL_DATA_ITEM_ID) {}
-    inline ~BatteryLevelDataItemBase() {}
-    inline virtual DataItemId getId() { return mId; }
-// Data members
-    uint8_t mBatteryPct;
-protected:
-    DataItemId mId;
-};
-
-} // namespace loc_core
-
-#endif //__DATAITEMCONCRETEBASETYPES__
diff --git a/gps/core/data-items/DataItemsFactoryProxy.cpp b/gps/core/data-items/DataItemsFactoryProxy.cpp
index 10f73f4..6ffb997 100644
--- a/gps/core/data-items/DataItemsFactoryProxy.cpp
+++ b/gps/core/data-items/DataItemsFactoryProxy.cpp
@@ -32,50 +32,95 @@
 #include <DataItemId.h>
 #include <IDataItemCore.h>
 #include <DataItemsFactoryProxy.h>
+#include <DataItemConcreteTypes.h>
 #include <loc_pla.h>
 #include <log_util.h>
 #include "loc_misc_utils.h"
 
 namespace loc_core
 {
-void* DataItemsFactoryProxy::dataItemLibHandle = NULL;
-get_concrete_data_item_fn* DataItemsFactoryProxy::getConcreteDIFunc = NULL;
 
-IDataItemCore* DataItemsFactoryProxy::createNewDataItem(DataItemId id)
-{
+IDataItemCore* DataItemsFactoryProxy::createNewDataItem(IDataItemCore* dataItem) {
     IDataItemCore *mydi = nullptr;
 
-    if (NULL != getConcreteDIFunc) {
-        mydi = (*getConcreteDIFunc)(id);
-    }
-    else {
-        getConcreteDIFunc = (get_concrete_data_item_fn * )
-                dlGetSymFromLib(dataItemLibHandle, DATA_ITEMS_LIB_NAME, DATA_ITEMS_GET_CONCRETE_DI);
-
-        if (NULL != getConcreteDIFunc) {
-            LOC_LOGd("Loaded function %s : %p", DATA_ITEMS_GET_CONCRETE_DI, getConcreteDIFunc);
-            mydi = (*getConcreteDIFunc)(id);
-        }
-        else {
-            // dlysm failed.
-            const char * err = dlerror();
-            if (NULL == err)
-            {
-                err = "Unknown";
-            }
-            LOC_LOGe("failed to find symbol %s; error=%s", DATA_ITEMS_GET_CONCRETE_DI, err);
-        }
-    }
+    switch (dataItem->getId()) {
+    case AIRPLANEMODE_DATA_ITEM_ID:
+        mydi = new AirplaneModeDataItem(*((AirplaneModeDataItem*)dataItem));
+        break;
+    case ENH_DATA_ITEM_ID:
+        mydi = new ENHDataItem(*((ENHDataItem*)dataItem));
+        break;
+    case GPSSTATE_DATA_ITEM_ID:
+        mydi = new GPSStateDataItem(*((GPSStateDataItem*)dataItem));
+        break;
+    case NLPSTATUS_DATA_ITEM_ID:
+        mydi = new NLPStatusDataItem(*((NLPStatusDataItem*)dataItem));
+        break;
+    case WIFIHARDWARESTATE_DATA_ITEM_ID:
+        mydi = new WifiHardwareStateDataItem(*((WifiHardwareStateDataItem*)dataItem));
+        break;
+    case NETWORKINFO_DATA_ITEM_ID:
+        mydi = new NetworkInfoDataItem(*((NetworkInfoDataItem*)dataItem));
+        break;
+    case SERVICESTATUS_DATA_ITEM_ID:
+       mydi = new ServiceStatusDataItem(*((ServiceStatusDataItem*)dataItem));
+        break;
+    case RILCELLINFO_DATA_ITEM_ID:
+        mydi = new RilCellInfoDataItem(*((RilCellInfoDataItem*)dataItem));
+        break;
+    case RILSERVICEINFO_DATA_ITEM_ID:
+        mydi = new RilServiceInfoDataItem(*((RilServiceInfoDataItem*)dataItem));
+        break;
+    case MODEL_DATA_ITEM_ID:
+        mydi = new ModelDataItem(*((ModelDataItem*)dataItem));
+        break;
+    case MANUFACTURER_DATA_ITEM_ID:
+        mydi = new ManufacturerDataItem(*((ManufacturerDataItem*)dataItem));
+        break;
+    case ASSISTED_GPS_DATA_ITEM_ID:
+        mydi = new AssistedGpsDataItem(*((AssistedGpsDataItem*)dataItem));
+        break;
+    case SCREEN_STATE_DATA_ITEM_ID:
+        mydi = new ScreenStateDataItem(*((ScreenStateDataItem*)dataItem));
+        break;
+    case POWER_CONNECTED_STATE_DATA_ITEM_ID:
+        mydi = new PowerConnectStateDataItem(*((PowerConnectStateDataItem*)dataItem));
+        break;
+    case TIMEZONE_CHANGE_DATA_ITEM_ID:
+        mydi = new TimeZoneChangeDataItem(*((TimeZoneChangeDataItem*)dataItem));
+        break;
+    case TIME_CHANGE_DATA_ITEM_ID:
+        mydi = new TimeChangeDataItem(*((TimeChangeDataItem*)dataItem));
+        break;
+    case WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID:
+        mydi = new WifiSupplicantStatusDataItem(*((WifiSupplicantStatusDataItem*)dataItem));
+        break;
+    case SHUTDOWN_STATE_DATA_ITEM_ID:
+        mydi = new ShutdownStateDataItem(*((ShutdownStateDataItem*)dataItem));
+        break;
+    case TAC_DATA_ITEM_ID:
+        mydi = new TacDataItem(*((TacDataItem*)dataItem));
+        break;
+    case MCCMNC_DATA_ITEM_ID:
+        mydi = new MccmncDataItem(*((MccmncDataItem*)dataItem));
+        break;
+    case BTLE_SCAN_DATA_ITEM_ID:
+        mydi = new BtLeDeviceScanDetailsDataItem(*((BtLeDeviceScanDetailsDataItem*)dataItem));
+        break;
+    case BT_SCAN_DATA_ITEM_ID:
+        mydi = new BtDeviceScanDetailsDataItem(*((BtDeviceScanDetailsDataItem*)dataItem));
+        break;
+    case BATTERY_LEVEL_DATA_ITEM_ID:
+        mydi = new BatteryLevelDataItem(*((BatteryLevelDataItem*)dataItem));
+        break;
+    case INVALID_DATA_ITEM_ID:
+    case MAX_DATA_ITEM_ID:
+    default:
+        break;
+    };
     return mydi;
 }
 
-void DataItemsFactoryProxy::closeDataItemLibraryHandle()
-{
-    if (NULL != dataItemLibHandle) {
-        dlclose(dataItemLibHandle);
-        dataItemLibHandle = NULL;
-    }
-}
 
 } // namespace loc_core
 
diff --git a/gps/core/data-items/DataItemsFactoryProxy.h b/gps/core/data-items/DataItemsFactoryProxy.h
index cfd447d..f46737f 100644
--- a/gps/core/data-items/DataItemsFactoryProxy.h
+++ b/gps/core/data-items/DataItemsFactoryProxy.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -35,18 +35,9 @@
 
 namespace loc_core
 {
-
-#define DATA_ITEMS_LIB_NAME "libdataitems.so"
-#define DATA_ITEMS_GET_CONCRETE_DI "getConcreteDataItem"
-
-typedef IDataItemCore * (get_concrete_data_item_fn)(DataItemId);
-
 class DataItemsFactoryProxy {
 public:
-    static IDataItemCore* createNewDataItem(DataItemId id);
-    static void closeDataItemLibraryHandle();
-    static void *dataItemLibHandle;
-    static get_concrete_data_item_fn *getConcreteDIFunc;
+    static IDataItemCore* createNewDataItem(IDataItemCore* di);
 };
 
 } // namespace loc_core
diff --git a/gps/core/data-items/IDataItemCore.h b/gps/core/data-items/IDataItemCore.h
index 6084c92..80e4e47 100644
--- a/gps/core/data-items/IDataItemCore.h
+++ b/gps/core/data-items/IDataItemCore.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 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
@@ -49,7 +49,7 @@
      * @details Gets Data item id.
      * @return Data item id.
      */
-    virtual DataItemId getId () = 0;
+    inline DataItemId getId() { return mId; }
 
     /**
      * @brief Stringify.
@@ -68,13 +68,15 @@
      *
      * @return Zero for success or non zero for failure.
      */
-    virtual int32_t copy (IDataItemCore * src, bool *dataItemCopied = nullptr) = 0;
+    virtual int32_t copyFrom(IDataItemCore * src) = 0;
 
     /**
      * @brief Destructor.
      * @details Destructor.
      */
     virtual ~IDataItemCore () {}
+protected:
+    DataItemId mId = INVALID_DATA_ITEM_ID;
 };
 
 } // namespace loc_core
diff --git a/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy b/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy
index 38a41f9..b616bd6 100644
--- a/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy
+++ b/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy
@@ -29,6 +29,13 @@
 #
 #******************************************************************************
 
+#******************************************************************************
+# Changes from Qualcomm Innovation Center are provided under the following license:
+# Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause-Clear
+#
+#******************************************************************************
+
 fdatasync: 1
 getdents64: 1
 gettimeofday: 1
@@ -71,3 +78,6 @@
 chmod: 1
 lseek: 1
 geteuid32: 1
+getrlimit: 1
+shutdown: 1
+
diff --git a/gps/gnss/NativeAgpsHandler.cpp b/gps/gnss/NativeAgpsHandler.cpp
index ce4c03a..d52eeeb 100644
--- a/gps/gnss/NativeAgpsHandler.cpp
+++ b/gps/gnss/NativeAgpsHandler.cpp
@@ -32,7 +32,7 @@
 #include <SystemStatus.h>
 #include <DataItemId.h>
 #include <DataItemsFactoryProxy.h>
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 #include <loc_log.h>
 #include <NativeAgpsHandler.h>
 #include <GnssAdapter.h>
@@ -48,8 +48,8 @@
     for (auto each : dlist) {
         switch (each->getId()) {
             case NETWORKINFO_DATA_ITEM_ID: {
-                    NetworkInfoDataItemBase* networkInfo =
-                        static_cast<NetworkInfoDataItemBase*>(each);
+                    NetworkInfoDataItem* networkInfo =
+                        static_cast<NetworkInfoDataItem*>(each);
                     uint64_t mobileBit = (uint64_t )1 << loc_core::TYPE_MOBILE;
                     uint64_t allTypes = networkInfo->mAllTypes;
                     mConnected = ((networkInfo->mAllTypes & mobileBit) == mobileBit);
diff --git a/gps/gnss/XtraSystemStatusObserver.cpp b/gps/gnss/XtraSystemStatusObserver.cpp
index e04335a..6f0a348 100644
--- a/gps/gnss/XtraSystemStatusObserver.cpp
+++ b/gps/gnss/XtraSystemStatusObserver.cpp
@@ -47,7 +47,7 @@
 #include <LocAdapterBase.h>
 #include <DataItemId.h>
 #include <DataItemsFactoryProxy.h>
-#include <DataItemConcreteTypesBase.h>
+#include <DataItemConcreteTypes.h>
 
 using namespace loc_util;
 using namespace loc_core;
@@ -322,13 +322,10 @@
                 const list<IDataItemCore*>& dataItemList) :
                 mXtraSysStatObj(xtraSysStatObs) {
             for (auto eachItem : dataItemList) {
-                IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(
-                        eachItem->getId());
+                IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(eachItem);
                 if (NULL == dataitem) {
                     break;
                 }
-                // Copy the contents of the data item
-                dataitem->copy(eachItem);
 
                 mDataItemList.push_back(dataitem);
             }
@@ -349,8 +346,7 @@
                 {
                     case NETWORKINFO_DATA_ITEM_ID:
                     {
-                        NetworkInfoDataItemBase* networkInfo =
-                                static_cast<NetworkInfoDataItemBase*>(each);
+                        NetworkInfoDataItem* networkInfo = static_cast<NetworkInfoDataItem*>(each);
                         NetworkInfoType* networkHandleInfo =
                                 static_cast<NetworkInfoType*>(networkInfo->getNetworkHandle());
                         mXtraSysStatObj->updateConnections(networkInfo->getAllTypes(),
@@ -360,16 +356,14 @@
 
                     case TAC_DATA_ITEM_ID:
                     {
-                        TacDataItemBase* tac =
-                                 static_cast<TacDataItemBase*>(each);
+                        TacDataItem* tac = static_cast<TacDataItem*>(each);
                         mXtraSysStatObj->updateTac(tac->mValue);
                     }
                     break;
 
                     case MCCMNC_DATA_ITEM_ID:
                     {
-                        MccmncDataItemBase* mccmnc =
-                                static_cast<MccmncDataItemBase*>(each);
+                        MccmncDataItem* mccmnc = static_cast<MccmncDataItem*>(each);
                         mXtraSysStatObj->updateMccMnc(mccmnc->mValue);
                     }
                     break;
diff --git a/gps/location/LocationAPIClientBase.cpp b/gps/location/LocationAPIClientBase.cpp
index ea15a76..58a8c17 100644
--- a/gps/location/LocationAPIClientBase.cpp
+++ b/gps/location/LocationAPIClientBase.cpp
@@ -26,6 +26,11 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #define LOG_NDEBUG 0
 #define LOG_TAG "LocSvc_APIClientBase"
 
@@ -357,7 +362,8 @@
     pthread_mutex_lock(&mMutex);
     if (mLocationAPI) {
         if (mTracking) {
-            LOC_LOGW("%s:%d] Existing tracking session present", __FUNCTION__, __LINE__);
+            pthread_mutex_unlock(&mMutex);
+            locAPIUpdateTrackingOptions(options);
         } else {
             uint32_t session = mLocationAPI->startTracking(options);
             LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
@@ -367,11 +373,13 @@
             mRequestQueues[REQUEST_TRACKING].reset(session);
             mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this));
             mTracking = true;
+            pthread_mutex_unlock(&mMutex);
         }
 
         retVal = LOCATION_ERROR_SUCCESS;
+    } else {
+        pthread_mutex_unlock(&mMutex);
     }
-    pthread_mutex_unlock(&mMutex);
 
     return retVal;
 }
diff --git a/location/Android.bp b/location/Android.bp
index fb78f04..395136c 100644
--- a/location/Android.bp
+++ b/location/Android.bp
@@ -2,19 +2,3 @@
     "-Werror",
     "-Wno-undefined-bool-conversion",
 ]
-
-/* Activate the following for debug purposes only,
-   comment out for production */
-GNSS_SANITIZE_DIAG = {
-/*
-    diag: {
-        cfi: true,
-        misc_undefined: [
-            "bounds",
-            "null",
-            "unreachable",
-            "integer",
-        ],
-    },
-*/
-}
diff --git a/location/Android.mk b/location/Android.mk
index 30e4eee..fa0ff5d 100644
--- a/location/Android.mk
+++ b/location/Android.mk
@@ -1,6 +1,5 @@
 LOCAL_PATH := $(call my-dir)
 
-GNSS_SANITIZE_DIAG := cfi bounds null unreachable integer address
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
 
diff --git a/location/utils/loc_socket/Android.mk b/location/utils/loc_socket/Android.mk
index 1f9c1d9..f2972eb 100644
--- a/location/utils/loc_socket/Android.mk
+++ b/location/utils/loc_socket/Android.mk
@@ -3,8 +3,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := libloc_socket
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
 LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
 LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
 LOCAL_MODULE_TAGS := optional