Add DataItemObserver interface in SystemStatus

Add DataItemObserver interface in SystemStatus so
that clients can subscribe dataitem events from
SystemStatus. Also moving DateItem and its observer,
subscription classes into HAL

Simplify DataItem class implementation.

Change-Id: I7b2c3fc9dcf67dd6132bbcccda874e3f7ed6fa94
CRs-Fixed: 2041019 2072896
diff --git a/core/Android.mk b/core/Android.mk
index ee07c19..dba0b0a 100644
--- a/core/Android.mk
+++ b/core/Android.mk
@@ -31,12 +31,22 @@
     ContextBase.cpp \
     LocDualContext.cpp \
     loc_core_log.cpp \
+    data-items/DataItemsFactoryProxy.cpp \
+    data-items/common/ClientIndex.cpp \
+    data-items/common/DataItemIndex.cpp \
+    data-items/common/IndexFactory.cpp \
+    SystemStatusOsObserver.cpp \
     SystemStatus.cpp
 
 LOCAL_CFLAGS += \
      -fno-short-enums \
      -D_ANDROID_
 
+LOCAL_C_INCLUDES:= \
+    $(LOCAL_PATH)/data-items \
+    $(LOCAL_PATH)/data-items/common \
+    $(LOCAL_PATH)/observer \
+
 LOCAL_HEADER_LIBRARIES := \
     libgps.utils_headers \
     libloc_pla_headers \
@@ -48,7 +58,11 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := libloc_core_headers
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH) \
+    $(LOCAL_PATH)/data-items \
+    $(LOCAL_PATH)/data-items/common \
+    $(LOCAL_PATH)/observer
 include $(BUILD_HEADER_LIBRARY)
 
 endif # not BUILD_TINY_ANDROID
diff --git a/core/LocDualContext.cpp b/core/LocDualContext.cpp
index 90eacff..fd3450d 100644
--- a/core/LocDualContext.cpp
+++ b/core/LocDualContext.cpp
@@ -35,7 +35,6 @@
 #include <msg_q.h>
 #include <platform_lib_log_util.h>
 #include <loc_log.h>
-#include <SystemStatus.h>
 
 namespace loc_core {
 
@@ -57,7 +56,6 @@
 ContextBase* LocDualContext::mFgContext = NULL;
 ContextBase* LocDualContext::mBgContext = NULL;
 ContextBase* LocDualContext::mInjectContext = NULL;
-SystemStatus* LocDualContext::mSystemStatus = NULL;
 // the name must be shorter than 15 chars
 const char* LocDualContext::mLocationHalName = "Loc_hal_worker";
 #ifndef USE_GLIB
@@ -149,14 +147,4 @@
 {
 }
 
-SystemStatus* LocDualContext::getSystemStatus(void)
-{
-    pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
-    if (NULL == mSystemStatus) {
-        mSystemStatus = new SystemStatus();
-    }
-    pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
-    return  mSystemStatus;
-}
-
 }
diff --git a/core/LocDualContext.h b/core/LocDualContext.h
index 7642152..3b3ce2c 100644
--- a/core/LocDualContext.h
+++ b/core/LocDualContext.h
@@ -36,8 +36,6 @@
 
 namespace loc_core {
 
-class SystemStatus;
-
 class LocDualContext : public ContextBase {
     static const MsgTask* mMsgTask;
     static ContextBase* mFgContext;
@@ -47,7 +45,6 @@
                                      const char* name, bool joinable = true);
     static const MsgTask* getMsgTask(const char* name, bool joinable = true);
     static pthread_mutex_t mGetLocContextMutex;
-    static SystemStatus* mSystemStatus;
 
 protected:
     LocDualContext(const MsgTask* msgTask,
@@ -72,7 +69,6 @@
     }
 
     static void injectFeatureConfig(ContextBase *context);
-    static SystemStatus* getSystemStatus(void);
 };
 
 }
diff --git a/core/Makefile.am b/core/Makefile.am
index 5d52c40..568880c 100644
--- a/core/Makefile.am
+++ b/core/Makefile.am
@@ -17,6 +17,13 @@
            UlpProxyBase.h \
            loc_core_log.h \
            LocAdapterProxyBase.h \
+           data-items/DataItemId.h \
+           data-items/IDataItemCore.h \
+           observer/IDataItemObserver.h \
+           observer/IDataItemSubscription.h \
+           observer/IFrameworkActionReq.h \
+           observer/IOsObserver.h \
+           SystemStatusOsObserver.h \
            SystemStatus.h
 
 libloc_core_la_c_sources = \
@@ -25,6 +32,11 @@
            ContextBase.cpp \
            LocDualContext.cpp \
            loc_core_log.cpp \
+           data-items/DataItemsFactoryProxy.cpp \
+           data-items/common/ClientIndex.cpp \
+           data-items/common/DataItemIndex.cpp \
+           data-items/common/IndexFactory.cpp \
+           SystemStatusOsObserver.cpp \
            SystemStatus.cpp
 
 library_includedir = $(pkgincludedir)/core
diff --git a/core/SystemStatus.cpp b/core/SystemStatus.cpp
index 50cb4ed..dc03604 100644
--- a/core/SystemStatus.cpp
+++ b/core/SystemStatus.cpp
@@ -35,8 +35,10 @@
 #include <sys/time.h>
 #include <pthread.h>
 #include <platform_lib_log_util.h>
+#include <MsgTask.h>
 #include <loc_nmea.h>
 #include <SystemStatus.h>
+#include <SystemStatusOsObserver.h>
 
 namespace loc_core
 {
@@ -1176,10 +1178,44 @@
 /******************************************************************************
  SystemStatus
 ******************************************************************************/
-pthread_mutex_t SystemStatus::mMutexSystemStatus = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t   SystemStatus::mMutexSystemStatus = PTHREAD_MUTEX_INITIALIZER;
+SystemStatus*     SystemStatus::mInstance = NULL;
 
-SystemStatus::SystemStatus()
+SystemStatus* SystemStatus::getInstance(const MsgTask* msgTask)
 {
+    pthread_mutex_lock(&mMutexSystemStatus);
+
+    if (!mInstance) {
+        // Instantiating for the first time. msgTask should not be NULL
+        if (msgTask == NULL) {
+            LOC_LOGE("SystemStatus: msgTask is NULL!!");
+            pthread_mutex_unlock(&mMutexSystemStatus);
+            return NULL;
+        }
+        mInstance = new (nothrow) SystemStatus(msgTask);
+        LOC_LOGD("SystemStatus::getInstance:%p. Msgtask:%p", mInstance, msgTask);
+    }
+
+    pthread_mutex_unlock(&mMutexSystemStatus);
+    return mInstance;
+}
+
+void SystemStatus::destroyInstance()
+{
+    delete mInstance;
+    mInstance = NULL;
+}
+
+IOsObserver* SystemStatus::getOsObserver()
+{
+    return &mSysStatusObsvr;
+}
+
+SystemStatus::SystemStatus(const MsgTask* msgTask) :
+    mSysStatusObsvr(msgTask)
+{
+    int result = 0;
+    ENTRY_LOG ();
     mCache.mLocation.clear();
 
     mCache.mTimeAndClock.clear();
@@ -1196,6 +1232,8 @@
     mCache.mNavData.clear();
 
     mCache.mPositionFailure.clear();
+
+    EXIT_LOG_WITH_ERROR ("%d",result);
 }
 
 /******************************************************************************
diff --git a/core/SystemStatus.h b/core/SystemStatus.h
index 78fc6f8..8cf75b5 100644
--- a/core/SystemStatus.h
+++ b/core/SystemStatus.h
@@ -30,7 +30,13 @@
 #define __SYSTEM_STATUS__
 
 #include <stdint.h>
+#include <string>
 #include <vector>
+#include <platform_lib_log_util.h>
+#include <MsgTask.h>
+#include <IOsObserver.h>
+#include <SystemStatusOsObserver.h>
+
 #include <gps_extended_c.h>
 
 #define GPS_MIN  (1)   //1-32
@@ -390,7 +396,16 @@
 ******************************************************************************/
 class SystemStatus
 {
-    static pthread_mutex_t mMutexSystemStatus;
+private:
+    static SystemStatus                       *mInstance;
+    SystemStatusOsObserver                    mSysStatusObsvr;
+    // ctor
+    SystemStatus(const MsgTask* msgTask);
+    // dtor
+    inline ~SystemStatus() {}
+
+    // Data members
+    static pthread_mutex_t                    mMutexSystemStatus;
 
     static const uint32_t                     maxLocation = 5;
 
@@ -429,9 +444,12 @@
     bool setPositionFailure(const SystemStatusPQWS1& nmea);
 
 public:
-    SystemStatus();
-    ~SystemStatus() { }
+    // Static methods
+    static SystemStatus* getInstance(const MsgTask* msgTask);
+    static void destroyInstance();
+    IOsObserver* getOsObserver();
 
+    // Helpers
     bool eventPosition(const UlpLocation& location,const GpsLocationExtended& locationEx);
     bool setNmeaString(const char *data, uint32_t len);
     bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
diff --git a/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp
new file mode 100644
index 0000000..e327f93
--- /dev/null
+++ b/core/SystemStatusOsObserver.cpp
@@ -0,0 +1,646 @@
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#define LOG_TAG "LocSvc_SystemStatusOsObserver"
+
+#include <string>
+#include <cinttypes>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <iterator>
+#include <algorithm>
+
+#include <MsgTask.h>
+#include <SystemStatusOsObserver.h>
+
+#include <DataItemId.h>
+#include <IDataItemCore.h>
+#include <IClientIndex.h>
+#include <IDataItemIndex.h>
+#include <IndexFactory.h>
+
+#include <DataItemsFactoryProxy.h>
+
+#include <platform_lib_log_util.h>
+
+namespace loc_core
+{
+#define BREAK_IF_ZERO(ERR,X) if(0==(X)) {result = (ERR); break;}
+#define BREAK_IF_NON_ZERO(ERR,X) if(0!=(X)) {result = (ERR); break;}
+
+SystemStatusOsObserver::SystemStatusOsObserver(const MsgTask* msgTask) :
+    mAddress ("SystemStatusOsObserver"),
+    mClientIndex(IndexFactory <IDataItemObserver *, DataItemId> :: createClientIndex ()),
+    mDataItemIndex(IndexFactory <IDataItemObserver *, DataItemId> :: createDataItemIndex ())
+{
+    int result = -1;
+    ENTRY_LOG ();
+    do {
+        BREAK_IF_ZERO (1, mClientIndex);
+        BREAK_IF_ZERO (2, mDataItemIndex);
+        mContext.mMsgTask = msgTask;
+        result = 0;
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+SystemStatusOsObserver :: ~SystemStatusOsObserver ()
+{
+    // Close data-item library handle
+    DataItemsFactoryProxy::closeDataItemLibraryHandle();
+
+    // Destroy cache
+    map <DataItemId, IDataItemCore *> :: iterator citer = mDataItemCache.begin ();
+    for (; citer != mDataItemCache.end (); ++citer) {
+        if (citer->second != NULL) { delete citer->second; }
+    }
+    mDataItemCache.clear ();
+    delete mClientIndex;
+    delete mDataItemIndex;
+    mClientIndex = NULL;
+    mDataItemIndex = NULL;
+}
+
+/******************************************************************************
+ Message proc
+******************************************************************************/
+void SystemStatusOsObserver :: HandleSubscribeReq :: proc () const {
+
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mDataItemList.empty ()) {
+            LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
+            result = 0;
+            break;
+        }
+        //mDataItemList.sort ();
+        // Handle First Response
+        list <DataItemId> pendingFirstResponseList;
+        this->mParent->mClientIndex->add (this->mClient, mDataItemList, pendingFirstResponseList);
+
+        // Do not send first response for only pendingFirstResponseList,
+        // instead send for all the data items  (present in the cache) that
+        // have been subscribed for each time.
+        this->mParent->sendFirstResponse (mDataItemList, this->mClient);
+
+        list <DataItemId> yetToSubscribeDataItemsList;
+        this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList);
+        // Send subscription list to framework
+        if (!yetToSubscribeDataItemsList.empty ()) {
+            this->mParent->mContext.mSubscriptionObj->subscribe
+            (
+                yetToSubscribeDataItemsList,
+                this->mParent
+            );
+            LOC_LOGD ("Subscribe Request sent to framework for the following data items");
+            this->mParent->logMe (yetToSubscribeDataItemsList);
+        }
+
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+    return;
+}
+
+void SystemStatusOsObserver :: HandleUpdateSubscriptionReq :: proc () const {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mDataItemList.empty ()) {
+            LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
+            result = 0;
+            break;
+        }
+        //mDataItemList.sort ();
+        list <DataItemId> currentlySubscribedList;
+        this->mParent->mClientIndex->getSubscribedList (this->mClient, currentlySubscribedList);
+        list <DataItemId> removeDataItemList;
+        set_difference (currentlySubscribedList.begin (), currentlySubscribedList.end (),
+                       mDataItemList.begin (), mDataItemList.end (),
+                       inserter (removeDataItemList,removeDataItemList.begin ()));
+        // Handle First Response
+        list <DataItemId> pendingFirstResponseList;
+        this->mParent->mClientIndex->add (this->mClient, mDataItemList, pendingFirstResponseList);
+        // Send First Response
+        this->mParent->sendFirstResponse (pendingFirstResponseList, this->mClient);
+
+        list <DataItemId> yetToSubscribeDataItemsList;
+        this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList);
+        // Send subscription list to framework
+        if (!yetToSubscribeDataItemsList.empty ()) {
+            this->mParent->mContext.mSubscriptionObj->subscribe
+            (
+                yetToSubscribeDataItemsList,
+                this->mParent
+            );
+            LOC_LOGD ("Subscribe Request sent to framework for the following data items");
+            this->mParent->logMe (yetToSubscribeDataItemsList);
+        }
+
+        list <DataItemId> unsubscribeList;
+        list <DataItemId> unused;
+        this->mParent->mClientIndex->remove (this->mClient, removeDataItemList, unused);
+
+        if (!this->mParent->mClientIndex->isSubscribedClient (this->mClient)) {
+            this->mParent->mDataItemIndex->remove (list <IDataItemObserver *> (1,this->mClient), unsubscribeList);
+        }
+        if (!unsubscribeList.empty ()) {
+            // Send unsubscribe to framework
+            this->mParent->mContext.mSubscriptionObj->unsubscribe
+            (
+                unsubscribeList,
+                this->mParent
+            );
+            LOC_LOGD ("Unsubscribe Request sent to framework for the following data items");
+            this->mParent->logMe (unsubscribeList);
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: HandleRequestData :: proc () const {
+    int result = 0;
+    ENTRY_LOG ();
+
+    do {
+        if (mDataItemList.empty ()) {
+            LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
+            result = 0;
+            break;
+        }
+        //mDataItemList.sort ();
+        list <DataItemId> yetToSubscribeDataItemsList;
+        this->mParent->mClientIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList);
+        this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList);
+        // Send subscription list to framework
+        if (!mDataItemList.empty ()) {
+            this->mParent->mContext.mSubscriptionObj->requestData
+            (
+                mDataItemList,
+                this->mParent
+            );
+            LOC_LOGD ("Subscribe Request sent to framework for the following data items");
+            this->mParent->logMe (yetToSubscribeDataItemsList);
+        }
+
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: HandleUnsubscribeReq :: proc () const {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mDataItemList.empty ()) {
+            LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
+            result = 0;
+            break;
+        }
+        //mDataItemList.sort ();
+        list <DataItemId> unsubscribeList;
+        list <DataItemId> unused;
+        this->mParent->mClientIndex->remove (this->mClient, mDataItemList, unused);
+
+        list <DataItemId> :: const_iterator it = mDataItemList.begin ();
+        for (; it != mDataItemList.end (); ++it) {
+            list <IDataItemObserver *> clientListSubs;
+            list <IDataItemObserver *> clientListOut;
+            this->mParent->mDataItemIndex->remove ((*it),
+                                list <IDataItemObserver *> (1,this->mClient), clientListOut);
+            // check if there are any other subscribed client for this data item id
+            this->mParent->mDataItemIndex->getListOfSubscribedClients ( (*it), clientListSubs);
+            if (clientListSubs.empty())
+            {
+                LOC_LOGD ("Client list subscribed is empty for dataitem - %d",(*it));
+                unsubscribeList.push_back((*it));
+            }
+        }
+        if (!unsubscribeList.empty ()) {
+            // Send unsubscribe to framework
+            this->mParent->mContext.mSubscriptionObj->unsubscribe
+            (
+                unsubscribeList,
+                this->mParent
+            );
+            LOC_LOGD ("Unsubscribe Request sent to framework for the following data items");
+            this->mParent->logMe (unsubscribeList);
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: HandleUnsubscribeAllReq :: proc () const {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        list <IDataItemObserver *> clients (1, this->mClient);
+        list <DataItemId> unsubscribeList;
+        BREAK_IF_NON_ZERO (2, this->mParent->mClientIndex->remove (this->mClient));
+
+
+        this->mParent->mDataItemIndex->remove (clients, unsubscribeList);
+        if (!unsubscribeList.empty ()) {
+            // Send unsubscribe to framework
+            this->mParent->mContext.mSubscriptionObj->unsubscribe
+            (
+                unsubscribeList,
+                this->mParent
+            );
+            LOC_LOGD ("Unsubscribe Request sent to framework for the following data items");
+            this->mParent->logMe (unsubscribeList);
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: HandleNotify :: getListOfClients
+ (const list <DataItemId> & dlist, list <IDataItemObserver *> & clients ) const {
+
+     list <DataItemId> :: const_iterator it = dlist.begin ();
+     for (; it != dlist.end (); ++it) {
+         list <IDataItemObserver *> clientList;
+         this->mParent->mDataItemIndex->getListOfSubscribedClients ( (*it), clientList);
+         list <IDataItemObserver *> :: iterator citer = clientList.begin ();
+         for (; citer != clientList.end (); ++citer) {
+             clients.push_back (*citer);
+         }
+         clientList.clear ();
+     }
+     // remove duplicates
+     clients.unique ();
+}
+
+void SystemStatusOsObserver :: HandleNotify :: proc () const {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        // Update Cache with received data items and prepare
+        // list of data items to be sent.
+        list <IDataItemCore *> :: const_iterator it = mDList.begin ();
+        list <DataItemId> dataItemIdsToBeSent;
+        for (; it != mDList.end (); ++it) {
+            bool dataItemUpdated = false;
+            this->mParent->updateCache (*it, dataItemUpdated);
+            if (dataItemUpdated) {
+                dataItemIdsToBeSent.push_back ( (*it)->getId ());
+            }
+        }
+
+        list <IDataItemObserver *> clientList;
+        this->getListOfClients (dataItemIdsToBeSent, clientList);
+        list <IDataItemObserver *> :: iterator citer = clientList.begin ();
+        // Send data item to all subscribed clients
+        LOC_LOGD ("LocTech-Label :: SystemStatusOsObserver :: Data Items Out");
+        for (; citer != clientList.end (); ++citer) {
+            do {
+                list <DataItemId> dataItemIdsSubscribedByThisClient;
+                list <DataItemId> dataItemIdsToBeSentForThisClient;
+                this->mParent->mClientIndex->getSubscribedList (*citer, dataItemIdsSubscribedByThisClient);
+                dataItemIdsSubscribedByThisClient.sort ();
+                dataItemIdsToBeSent.sort ();
+                set_intersection (dataItemIdsToBeSent.begin (),
+                                 dataItemIdsToBeSent.end (),
+                                 dataItemIdsSubscribedByThisClient.begin (),
+                                 dataItemIdsSubscribedByThisClient.end (),
+                                 inserter (dataItemIdsToBeSentForThisClient,
+                                         dataItemIdsToBeSentForThisClient.begin ()));
+                BREAK_IF_NON_ZERO (4,this->mParent->sendCachedDataItems (dataItemIdsToBeSentForThisClient, *citer));
+                dataItemIdsSubscribedByThisClient.clear ();
+                dataItemIdsToBeSentForThisClient.clear ();
+            } while (0);
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+}
+
+void SystemStatusOsObserver :: HandleTurnOn :: proc () const {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        // Send action turn on to framework
+        this->mParent->mContext.mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut);
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+}
+
+void SystemStatusOsObserver :: HandleTurnOff :: proc () const {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        // Send action turn off to framework
+        this->mParent->mContext.mFrameworkActionReqObj->turnOff(mDataItemId);
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+}
+
+/******************************************************************************
+ IDataItemSubscription Overrides
+******************************************************************************/
+void SystemStatusOsObserver :: subscribe (const list <DataItemId> & l, IDataItemObserver * client) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mContext.mSubscriptionObj != NULL) {
+            HandleSubscribeReq * msg = new  (nothrow) HandleSubscribeReq (this, l, client);
+            mContext.mMsgTask->sendMsg (msg);
+        }
+        else {
+            LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
+            result = 1;
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: updateSubscription (const list <DataItemId> & l, IDataItemObserver * client) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mContext.mSubscriptionObj != NULL) {
+            mContext.mMsgTask->sendMsg (new  (nothrow) HandleUpdateSubscriptionReq (this, l, client));
+        }
+        else {
+            LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
+            result = 1;
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: requestData (const list <DataItemId> & l, IDataItemObserver * client) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mContext.mSubscriptionObj != NULL) {
+            mContext.mMsgTask->sendMsg (new  (nothrow) HandleRequestData (this, l, client));
+        }
+        else {
+            LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
+            result = 1;
+        }
+    } while (0);
+
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: unsubscribe (const list <DataItemId> & l, IDataItemObserver * client) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mContext.mSubscriptionObj != NULL) {
+            mContext.mMsgTask->sendMsg (new  (nothrow) HandleUnsubscribeReq (this, l, client));
+        }
+        else {
+            LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
+            result = 1;
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+void SystemStatusOsObserver :: unsubscribeAll (IDataItemObserver * client) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mContext.mSubscriptionObj != NULL) {
+            mContext.mMsgTask->sendMsg (new  (nothrow) HandleUnsubscribeAllReq (this, client));
+        }
+        else {
+            LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
+            result = 1;
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+}
+
+/******************************************************************************
+ IDataItemObserver Overrides
+******************************************************************************/
+void SystemStatusOsObserver::getName(string & name) {
+    name = mAddress;
+}
+
+void SystemStatusOsObserver::notify(const std::list <IDataItemCore *> & dlist) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        list <IDataItemCore *> :: const_iterator it = dlist.begin ();
+        list <IDataItemCore *> dataItemList;
+        list <DataItemId> ids;
+        LOC_LOGD("LocTech-Label :: SystemStatusOsObserver :: Data Items In");
+        for (; it != dlist.end (); ++it) {
+            if (*it != NULL) {
+                string dv;
+                (*it)->stringify(dv);
+                LOC_LOGD("LocTech-Value :: Data Item Value: %s", dv.c_str ());
+                IDataItemCore * dataitem = DataItemsFactoryProxy::createNewDataItem((*it)->getId());
+                BREAK_IF_ZERO (2, dataitem);
+                // Copy contents into the newly created data item
+                dataitem->copy(*it);
+                dataItemList.push_back(dataitem);
+                ids.push_back((*it)->getId());
+            }
+        }
+        mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify (this, dataItemList));
+    } while  (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+}
+
+/******************************************************************************
+ IFrameworkActionReq Overrides
+******************************************************************************/
+void SystemStatusOsObserver :: turnOn (DataItemId dit, int timeOut) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mContext.mFrameworkActionReqObj != NULL) {
+            // Check if data item exists in mActiveRequestCount
+            map <DataItemId, int> :: iterator citer = mActiveRequestCount.find (dit);
+            if (citer == mActiveRequestCount.end ()) {
+                // Data item not found in map
+                // Add reference count as 1 and add dataitem to map
+                pair <DataItemId, int> cpair (dit, 1);
+                mActiveRequestCount.insert (cpair);
+                LOC_LOGD("Sending turnOn request");
+                // Send action turn on to framework
+                mContext.mMsgTask->sendMsg (new  (nothrow) HandleTurnOn (this, dit, timeOut));
+            } else {
+                // Found in map, update reference count
+                citer->second++;
+                LOC_LOGD("HandleTurnOn - Data item:%d Num_refs:%d",dit,citer->second);
+            }
+        }
+        else {
+            LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
+            result = 1;
+        }
+    } while (0);
+
+    EXIT_LOG_WITH_ERROR ("%d", result);
+}
+
+void SystemStatusOsObserver :: turnOff (DataItemId dit) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (mContext.mFrameworkActionReqObj != NULL) {
+            // Check if data item exists in mActiveRequestCount
+            map <DataItemId, int> :: iterator citer = mActiveRequestCount.find (dit);
+            if (citer != mActiveRequestCount.end ()) {
+                citer->second--;
+                LOC_LOGD("HandleTurnOff - Data item:%d Remaining Num_refs:%d",dit,citer->second);
+
+                if(citer->second == 0) {
+                    LOC_LOGD("Sending turnOff request");
+                    // if this was last reference, remove item from map and turn off module
+                    mActiveRequestCount.erase(citer);
+                    // Send action turn off to framework
+                    mContext.mMsgTask->sendMsg (new  (nothrow) HandleTurnOff (this, dit));
+                }
+            } else {
+                // Not found in map
+                LOC_LOGD ("Data item id %d not found in FrameworkModuleMap",dit);
+            }
+        }
+        else {
+            LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
+            result = 1;
+        }
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+}
+
+/******************************************************************************
+ Helpers
+******************************************************************************/
+void SystemStatusOsObserver :: logMe (const list <DataItemId> & l) {
+    list <DataItemId> :: const_iterator it = l.begin ();
+    for (;it != l.end (); ++it) {
+        LOC_LOGD ("DataItem %d",*it);
+    }
+}
+
+int SystemStatusOsObserver :: sendFirstResponse (const list <DataItemId> & l, IDataItemObserver * to) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        if (l.empty ()) {
+            LOC_LOGV("list is empty. Nothing to do. Exiting");
+            result = 0;
+            break;
+        }
+
+        string clientName;
+        to->getName (clientName);
+        LOC_LOGD ("First response sent for the following data items To Client: %s", clientName.c_str());
+
+        list <IDataItemCore *> dataItems;
+        list <DataItemId> :: const_iterator diditer = l.begin ();
+        for (; diditer != l.end (); ++diditer) {
+            map <DataItemId, IDataItemCore*> :: const_iterator citer = mDataItemCache.find (*diditer);
+            if (citer != mDataItemCache.end ()) {
+                string dv;
+                IDataItemCore * di = citer->second;
+                di->stringify (dv);
+                LOC_LOGD ("LocTech-Value :: Data Item: %s", dv.c_str ());
+                dataItems.push_back (citer->second);
+            }
+        }
+        if (dataItems.empty ()) {
+            LOC_LOGV("No items to notify. Nothing to do. Exiting");
+            result = 0;
+            break;
+        }
+
+        // Notify Client
+        to->notify (dataItems);
+
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+    return result;
+}
+
+int SystemStatusOsObserver :: sendCachedDataItems (const list <DataItemId> & l, IDataItemObserver * to) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        list <IDataItemCore *> dataItems;
+        list <DataItemId> :: const_iterator it = l.begin ();
+        string clientName;
+        to->getName (clientName);
+        LOC_LOGD ("LocTech-Value :: To Client: %s", clientName.c_str ());
+        for (; it != l.end (); ++it) {
+            string dv;
+            IDataItemCore * di = this->mDataItemCache [ (*it) ];
+            di->stringify (dv);
+            LOC_LOGI("LocTech-Value :: Data Item: %s >> %s", dv.c_str(), clientName.c_str());
+            dataItems.push_back (di);
+        }
+
+        to->notify (dataItems);
+
+    } while (0);
+    EXIT_LOG_WITH_ERROR ("%d", result);
+    return result;
+}
+
+int SystemStatusOsObserver :: updateCache (IDataItemCore * d, bool &dataItemUpdated) {
+    int result = 0;
+    ENTRY_LOG ();
+    do {
+        BREAK_IF_ZERO (1, d);
+        // Check if data item exists in cache
+        map <DataItemId, IDataItemCore*> :: iterator citer = mDataItemCache.find (d->getId ());
+        if (citer == mDataItemCache.end ()) {
+            // New data item; not found in cache
+            IDataItemCore * dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
+            BREAK_IF_ZERO (2, dataitem);
+            // Copy the contents of the data item
+            dataitem->copy (d);
+            pair <DataItemId, IDataItemCore*> cpair (d->getId (), dataitem);
+            // Insert in mDataItemCache
+            mDataItemCache.insert (cpair);
+            dataItemUpdated = true;
+        } else {
+            // Found in cache; Update cache if necessary
+            BREAK_IF_NON_ZERO(3, citer->second->copy (d, &dataItemUpdated));
+        }
+
+        if (dataItemUpdated) {
+            LOC_LOGV("DataItem:%d updated:%d", d->getId (), dataItemUpdated);
+        }
+    } while (0);
+
+    EXIT_LOG_WITH_ERROR ("%d", result);
+    return result;
+}
+
+} // namespace loc_core
+
diff --git a/core/SystemStatusOsObserver.h b/core/SystemStatusOsObserver.h
new file mode 100644
index 0000000..8e42d21
--- /dev/null
+++ b/core/SystemStatusOsObserver.h
@@ -0,0 +1,333 @@
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __SYSTEM_STATUS_OSOBSERVER__
+#define __SYSTEM_STATUS_OSOBSERVER__
+
+#include <stdint.h>
+#include <string>
+#include <list>
+#include <map>
+#include <new>
+#include <vector>
+#include <platform_lib_log_util.h>
+#include <DataItemId.h>
+#include <MsgTask.h>
+#include <IOsObserver.h>
+
+namespace loc_core
+{
+
+/******************************************************************************
+ SystemStatusOsObserver
+******************************************************************************/
+// Forward Declarations
+class IDataItemCore;
+
+template <typename CT, typename DIT>
+class IClientIndex;
+
+template <typename CT, typename DIT>
+class IDataItemIndex;
+
+struct SystemContext {
+    IDataItemSubscription *mSubscriptionObj;
+    IFrameworkActionReq *mFrameworkActionReqObj;
+    const MsgTask *mMsgTask;
+
+    inline SystemContext() :
+        mSubscriptionObj(NULL),
+        mFrameworkActionReqObj(NULL),
+        mMsgTask(NULL) {}
+};
+
+// Clients wanting to get data from OS/Framework would need to
+// subscribe with OSObserver using IDataItemSubscription interface.
+// Such clients would need to implement IDataItemObserver interface
+// to receive data when it becomes available.
+class SystemStatusOsObserver : public IOsObserver {
+
+public:
+    // ctor
+    SystemStatusOsObserver(const MsgTask* msgTask);
+
+    // dtor
+    ~SystemStatusOsObserver();
+
+    // To set the subscription object
+    inline void setSubscriptionObj(IDataItemSubscription *subscriptionObj) {
+        mContext.mSubscriptionObj = subscriptionObj;
+    };
+
+    // To set the framework action request object
+    inline void setFrameworkActionReqObj(IFrameworkActionReq *frameworkActionReqObj) {
+        mContext.mFrameworkActionReqObj = frameworkActionReqObj;
+    }
+
+    // IDataItemObserver Overrides
+    virtual void getName (string & name);
+    virtual void notify (const std::list <IDataItemCore *> & dlist);
+
+    // IDataItemSubscription Overrides
+    virtual void subscribe (const std :: list <DataItemId> & l, IDataItemObserver * client);
+    virtual void updateSubscription
+    (
+        const std :: list <DataItemId> & l,
+        IDataItemObserver * client
+    );
+    virtual void requestData
+    (
+        const std :: list <DataItemId> & l,
+        IDataItemObserver * client
+    );
+    virtual void unsubscribe (const std :: list <DataItemId> & l, IDataItemObserver * client);
+    virtual void unsubscribeAll (IDataItemObserver * client);
+
+    // IFrameworkActionReq Overrides
+    virtual void turnOn (DataItemId dit, int timeOut = 0);
+    virtual void turnOff (DataItemId dit);
+
+private:
+
+    SystemContext                                        mContext;
+    const string                                         mAddress;
+    IClientIndex <IDataItemObserver *, DataItemId>      *mClientIndex;
+    IDataItemIndex <IDataItemObserver *, DataItemId>    *mDataItemIndex;
+    map < DataItemId, IDataItemCore * >                  mDataItemCache;
+    map < DataItemId, int >                              mActiveRequestCount;
+
+    // Nested types
+    // Messages
+    struct HandleMsgBase : public LocMsg {
+        HandleMsgBase (SystemStatusOsObserver * parent);
+        virtual ~HandleMsgBase ();
+        // Data members
+        SystemStatusOsObserver * mParent;
+    };
+
+    // Helpers
+    int sendFirstResponse
+    (
+        const list <DataItemId> & l,
+        IDataItemObserver * to
+    );
+
+    int sendCachedDataItems
+    (
+        const list <DataItemId> & l,
+        IDataItemObserver * to
+    );
+
+    int updateCache (IDataItemCore * d, bool &dataItemUpdated);
+    void logMe (const list <DataItemId> & l);
+
+    // Messages
+    struct HandleClientMsg : public LocMsg {
+        HandleClientMsg (SystemStatusOsObserver * parent, IDataItemObserver * client);
+        virtual ~HandleClientMsg ();
+        // Data Members
+        SystemStatusOsObserver * mParent;
+        IDataItemObserver * mClient;
+    };
+
+    struct HandleSubscribeReq : public HandleClientMsg  {
+        HandleSubscribeReq (SystemStatusOsObserver * parent,
+                           const list <DataItemId> & l,
+                           IDataItemObserver * client);
+        virtual ~HandleSubscribeReq ();
+        void proc () const;
+        // Data members
+        const list <DataItemId> mDataItemList;
+    };
+
+    struct HandleUpdateSubscriptionReq : public HandleClientMsg  {
+        HandleUpdateSubscriptionReq (SystemStatusOsObserver * parent,
+                                    const list <DataItemId> & l,
+                                    IDataItemObserver * client);
+        virtual ~HandleUpdateSubscriptionReq ();
+        void proc () const;
+        // Data members
+        const list <DataItemId> mDataItemList;
+    };
+
+    struct HandleRequestData : public HandleClientMsg {
+       HandleRequestData (SystemStatusOsObserver * parent,
+                          const list <DataItemId> & l,
+                          IDataItemObserver * client);
+       virtual ~HandleRequestData ();
+       void proc () const;
+       const list <DataItemId> mDataItemList;
+    };
+
+    struct HandleUnsubscribeReq : public HandleClientMsg  {
+        HandleUnsubscribeReq (SystemStatusOsObserver * parent,
+                             const list <DataItemId> & l,
+                             IDataItemObserver * client);
+        virtual ~HandleUnsubscribeReq ();
+        void proc () const;
+        // Data members
+        const list <DataItemId> mDataItemList;
+    };
+
+    struct HandleUnsubscribeAllReq : public HandleClientMsg  {
+        HandleUnsubscribeAllReq
+        (
+            SystemStatusOsObserver * parent,
+            IDataItemObserver * client
+        );
+        virtual ~HandleUnsubscribeAllReq ();
+        void proc () const;
+    };
+
+    struct HandleNotify : public HandleMsgBase {
+        HandleNotify (SystemStatusOsObserver * parent, list <IDataItemCore *> dlist);
+        virtual ~HandleNotify ();
+        void getListOfClients
+        (
+            const list <DataItemId> & dlist,
+            list <IDataItemObserver *> & clients
+        ) const;
+        void proc () const;
+        // Data members
+        list <IDataItemCore *> mDList;
+    };
+
+    struct HandleTurnOn : public HandleMsgBase  {
+        HandleTurnOn (SystemStatusOsObserver * parent,
+                          const DataItemId dit,
+                          const int timeOut);
+        virtual ~HandleTurnOn ();
+        void proc () const;
+        // Data members
+        DataItemId mDataItemId;
+        int mTimeOut;
+    };
+
+    struct HandleTurnOff : public HandleMsgBase  {
+        HandleTurnOff (SystemStatusOsObserver * parent,const DataItemId dit);
+        virtual ~HandleTurnOff ();
+        void proc () const;
+        // Data members
+        DataItemId mDataItemId;
+    };
+
+};
+
+
+/******************************************************************************
+ Messages
+******************************************************************************/
+// Ctors
+inline SystemStatusOsObserver :: HandleMsgBase :: HandleMsgBase (SystemStatusOsObserver * parent)
+:
+mParent (parent)
+{}
+
+inline SystemStatusOsObserver :: HandleClientMsg :: HandleClientMsg
+(
+    SystemStatusOsObserver * parent,
+    IDataItemObserver * client
+)
+:
+mParent (parent),
+mClient (client)
+{}
+
+inline SystemStatusOsObserver :: HandleSubscribeReq :: HandleSubscribeReq
+ (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client)
+:
+HandleClientMsg (parent, client), mDataItemList (l)
+{}
+
+inline SystemStatusOsObserver :: HandleUpdateSubscriptionReq :: HandleUpdateSubscriptionReq
+ (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client)
+:
+HandleClientMsg (parent, client), mDataItemList (l)
+{}
+
+inline SystemStatusOsObserver :: HandleRequestData :: HandleRequestData
+ (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client)
+:
+HandleClientMsg (parent, client), mDataItemList (l)
+{}
+
+inline SystemStatusOsObserver :: HandleUnsubscribeReq :: HandleUnsubscribeReq
+ (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client)
+:
+HandleClientMsg (parent, client), mDataItemList (l)
+{}
+
+inline SystemStatusOsObserver :: HandleUnsubscribeAllReq :: HandleUnsubscribeAllReq
+ (SystemStatusOsObserver * parent, IDataItemObserver * client)
+:
+HandleClientMsg (parent, client)
+{}
+
+inline SystemStatusOsObserver :: HandleNotify :: HandleNotify
+ (SystemStatusOsObserver * parent, list <IDataItemCore *> dlist)
+:
+HandleMsgBase (parent), mDList (dlist)
+{}
+
+inline SystemStatusOsObserver :: HandleTurnOn :: HandleTurnOn
+ (SystemStatusOsObserver * parent, const DataItemId dit,const int timeOut)
+:
+HandleMsgBase (parent), mDataItemId (dit), mTimeOut (timeOut)
+{}
+
+inline SystemStatusOsObserver :: HandleTurnOff :: HandleTurnOff
+ (SystemStatusOsObserver * parent, const DataItemId dit)
+:
+HandleMsgBase (parent), mDataItemId (dit)
+{}
+
+// Dtors
+inline SystemStatusOsObserver :: HandleMsgBase :: ~HandleMsgBase () {}
+inline SystemStatusOsObserver :: HandleClientMsg :: ~HandleClientMsg () {}
+inline SystemStatusOsObserver :: HandleSubscribeReq :: ~HandleSubscribeReq () {}
+inline SystemStatusOsObserver :: HandleUpdateSubscriptionReq :: ~HandleUpdateSubscriptionReq() {}
+inline SystemStatusOsObserver :: HandleRequestData :: ~HandleRequestData() {}
+inline SystemStatusOsObserver :: HandleUnsubscribeReq :: ~HandleUnsubscribeReq () {}
+inline SystemStatusOsObserver :: HandleUnsubscribeAllReq :: ~HandleUnsubscribeAllReq () {}
+
+inline SystemStatusOsObserver :: HandleNotify :: ~HandleNotify () {
+    list <IDataItemCore *> :: iterator it = mDList.begin ();
+    for (; it != mDList.end (); ++it) {
+        delete *it;
+        *it = NULL;
+    }
+}
+
+inline SystemStatusOsObserver :: HandleTurnOn :: ~HandleTurnOn () {}
+inline SystemStatusOsObserver :: HandleTurnOff :: ~HandleTurnOff () {}
+
+
+} // namespace loc_core
+
+#endif //__SYSTEM_STATUS__
+
diff --git a/core/data-items/DataItemId.h b/core/data-items/DataItemId.h
new file mode 100644
index 0000000..1bf132a
--- /dev/null
+++ b/core/data-items/DataItemId.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __DATAITEMID_H__
+#define __DATAITEMID_H__
+
+/**
+ * Enumeration of Data Item types
+ * When add/remove/update changes are made to Data Items, this file needs to be updated
+ * accordingly
+ */
+typedef enum e_DataItemId {
+    INVALID_DATA_ITEM_ID = -1,
+    // 0 - 4
+    AIRPLANEMODE_DATA_ITEM_ID,
+    ENH_DATA_ITEM_ID,
+    GPSSTATE_DATA_ITEM_ID,
+    NLPSTATUS_DATA_ITEM_ID,
+    WIFIHARDWARESTATE_DATA_ITEM_ID,
+    // 5 - 9
+    NETWORKINFO_DATA_ITEM_ID,
+    RILVERSION_DATA_ITEM_ID,
+    RILSERVICEINFO_DATA_ITEM_ID,
+    RILCELLINFO_DATA_ITEM_ID,
+    SERVICESTATUS_DATA_ITEM_ID,
+    // 10 - 14
+    MODEL_DATA_ITEM_ID,
+    MANUFACTURER_DATA_ITEM_ID,
+    VOICECALL_DATA_ITEM,
+    ASSISTED_GPS_DATA_ITEM_ID,
+    SCREEN_STATE_DATA_ITEM_ID,
+    // 15 - 19
+    POWER_CONNECTED_STATE_DATA_ITEM_ID,
+    TIMEZONE_CHANGE_DATA_ITEM_ID,
+    TIME_CHANGE_DATA_ITEM_ID,
+    WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID,
+    SHUTDOWN_STATE_DATA_ITEM_ID,
+    // 20 - 24
+    TAC_DATA_ITEM_ID,
+    MCCMNC_DATA_ITEM_ID,
+    BTLE_SCAN_DATA_ITEM_ID,
+    BT_SCAN_DATA_ITEM_ID,
+    OEM_GTP_UPLOAD_TRIGGER_READY_ITEM_ID,
+    MAX_DATA_ITEM_ID
+} DataItemId;
+
+#endif // #ifndef __DATAITEMID_H__
diff --git a/core/data-items/DataItemsFactoryProxy.cpp b/core/data-items/DataItemsFactoryProxy.cpp
new file mode 100644
index 0000000..130eecf
--- /dev/null
+++ b/core/data-items/DataItemsFactoryProxy.cpp
@@ -0,0 +1,99 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#define LOG_TAG "DataItemsFactoryProxy"
+
+#include <dlfcn.h>
+#include <DataItemId.h>
+#include <IDataItemCore.h>
+#include <DataItemsFactoryProxy.h>
+#include <platform_lib_log_util.h>
+
+namespace loc_core
+{
+void* DataItemsFactoryProxy::dataItemLibHandle = NULL;
+get_concrete_data_item_fn* DataItemsFactoryProxy::getConcreteDIFunc = NULL;
+
+IDataItemCore* DataItemsFactoryProxy::createNewDataItem(DataItemId id)
+{
+    IDataItemCore *mydi = nullptr;
+
+    if (NULL != getConcreteDIFunc) {
+        mydi = (*getConcreteDIFunc)(id);
+    }
+    else {
+        // first call to this function, symbol not yet loaded
+        if (NULL == dataItemLibHandle) {
+            LOC_LOGD("Loaded library %s",DATA_ITEMS_LIB_NAME);
+            dataItemLibHandle = dlopen(DATA_ITEMS_LIB_NAME, RTLD_NOW);
+            if (NULL == dataItemLibHandle) {
+                // dlopen failed.
+                const char * err = dlerror();
+                if (NULL == err)
+                {
+                    err = "Unknown";
+                }
+                LOC_LOGE("%s:%d]: failed to load library %s; error=%s",
+                     __func__, __LINE__, DATA_ITEMS_LIB_NAME, err);
+            }
+        }
+
+        // load sym - if dlopen handle is obtained and symbol is not yet obtained
+        if (NULL != dataItemLibHandle) {
+            getConcreteDIFunc = (get_concrete_data_item_fn * )
+                                    dlsym(dataItemLibHandle, DATA_ITEMS_GET_CONCRETE_DI);
+            if (NULL != getConcreteDIFunc) {
+                LOC_LOGD("Loaded function %s : %x",DATA_ITEMS_GET_CONCRETE_DI,getConcreteDIFunc);
+                mydi = (*getConcreteDIFunc)(id);
+            }
+            else {
+                // dlysm failed.
+                const char * err = dlerror();
+                if (NULL == err)
+                {
+                    err = "Unknown";
+                }
+                LOC_LOGE("%s:%d]: failed to find symbol %s; error=%s",
+                         __func__, __LINE__, DATA_ITEMS_GET_CONCRETE_DI, err);
+            }
+        }
+    }
+    return mydi;
+}
+
+void DataItemsFactoryProxy::closeDataItemLibraryHandle()
+{
+    if (NULL != dataItemLibHandle) {
+        dlclose(dataItemLibHandle);
+        dataItemLibHandle = NULL;
+    }
+}
+
+} // namespace loc_core
+
+
diff --git a/core/data-items/DataItemsFactoryProxy.h b/core/data-items/DataItemsFactoryProxy.h
new file mode 100644
index 0000000..cfd447d
--- /dev/null
+++ b/core/data-items/DataItemsFactoryProxy.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __DATAITEMFACTORYBASE__
+#define __DATAITEMFACTORYBASE__
+
+#include <DataItemId.h>
+#include <IDataItemCore.h>
+
+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;
+};
+
+} // namespace loc_core
+
+#endif //__DATAITEMFACTORYBASE__
+
diff --git a/core/data-items/IDataItemCore.h b/core/data-items/IDataItemCore.h
new file mode 100644
index 0000000..6084c92
--- /dev/null
+++ b/core/data-items/IDataItemCore.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __IDATAITEMCORE_H__
+#define __IDATAITEMCORE_H__
+
+#include <string>
+#include <DataItemId.h>
+
+namespace loc_core {
+
+using namespace std;
+
+/**
+ * @brief IDataItemCore interface.
+ * @details IDataItemCore interface.
+ *
+ */
+class IDataItemCore {
+public:
+    /**
+     * @brief Gets Data item id.
+     * @details Gets Data item id.
+     * @return Data item id.
+     */
+    virtual DataItemId getId () = 0;
+
+    /**
+     * @brief Stringify.
+     * @details Stringify.
+     *
+     * @param valueStr Reference to string.
+     */
+    virtual void stringify (string & valueStr) = 0;
+
+    /**
+     * @brief copy.
+     * @details copy.
+     *
+     * @param src Where to copy from.
+     * @param dataItemCopied Boolean flag indicated whether or not copied.
+     *
+     * @return Zero for success or non zero for failure.
+     */
+    virtual int32_t copy (IDataItemCore * src, bool *dataItemCopied = nullptr) = 0;
+
+    /**
+     * @brief Destructor.
+     * @details Destructor.
+     */
+    virtual ~IDataItemCore () {}
+};
+
+} // namespace loc_core
+
+#endif // __IDATAITEMCORE_H__
diff --git a/core/data-items/common/ClientIndex.cpp b/core/data-items/common/ClientIndex.cpp
new file mode 100644
index 0000000..ffb5e1d
--- /dev/null
+++ b/core/data-items/common/ClientIndex.cpp
@@ -0,0 +1,171 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <algorithm>
+#include <iterator>
+#include <string>
+#include <platform_lib_log_util.h>
+#include <ClientIndex.h>
+#include <IDataItemObserver.h>
+#include <DataItemId.h>
+
+using namespace std;
+using namespace loc_core;
+
+template <typename CT, typename DIT>
+inline ClientIndex <CT,DIT> :: ClientIndex () {}
+
+template <typename CT, typename DIT>
+inline ClientIndex <CT,DIT> :: ~ClientIndex () {}
+
+template <typename CT, typename DIT>
+bool ClientIndex <CT,DIT> :: isSubscribedClient (CT client) {
+    bool result = false;
+    ENTRY_LOG ();
+    typename map < CT, list <DIT> > :: iterator it =
+        mDataItemsPerClientMap.find (client);
+    if (it != mDataItemsPerClientMap.end ()) {
+        result = true;
+    }
+    EXIT_LOG_WITH_ERROR ("%d",result);
+    return result;
+}
+
+template <typename CT, typename DIT>
+void ClientIndex <CT,DIT> :: getSubscribedList (CT client, list <DIT> & out) {
+    ENTRY_LOG ();
+    typename map < CT, list <DIT> > :: iterator it =
+        mDataItemsPerClientMap.find (client);
+    if (it != mDataItemsPerClientMap.end ()) {
+        out = it->second;
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+template <typename CT, typename DIT>
+int ClientIndex <CT,DIT> :: remove (CT client) {
+    int result = 0;
+    ENTRY_LOG ();
+    mDataItemsPerClientMap.erase (client);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+    return result;
+}
+
+template <typename CT, typename DIT>
+void ClientIndex <CT,DIT> :: remove (const list <DIT> & r, list <CT> & out) {
+    ENTRY_LOG ();
+    typename map < CT, list <DIT> > :: iterator dicIter =
+        mDataItemsPerClientMap.begin ();
+    while (dicIter != mDataItemsPerClientMap.end()) {
+        typename list <DIT> :: const_iterator it = r.begin ();
+        for (; it != r.end (); ++it) {
+            typename list <DIT> :: iterator iter =
+                find (dicIter->second.begin (), dicIter->second.end (), *it);
+            if (iter != dicIter->second.end ()) {
+                dicIter->second.erase (iter);
+            }
+        }
+        if (dicIter->second.empty ()) {
+            out.push_back (dicIter->first);
+            // Post-increment operator increases the iterator but returns the
+            // prevous one that will be invalidated by erase()
+            mDataItemsPerClientMap.erase (dicIter++);
+        } else {
+            ++dicIter;
+        }
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+template <typename CT, typename DIT>
+void ClientIndex <CT,DIT> :: remove
+(
+    CT client,
+    const list <DIT> & r,
+    list <DIT> & out
+)
+{
+    ENTRY_LOG ();
+    typename map < CT, list <DIT> > :: iterator dicIter =
+        mDataItemsPerClientMap.find (client);
+    if (dicIter != mDataItemsPerClientMap.end ()) {
+        set_intersection (dicIter->second.begin (), dicIter->second.end (),
+                         r.begin (), r.end (),
+                         inserter (out,out.begin ()));
+        if (!out.empty ()) {
+            typename list <DIT> :: iterator it = out.begin ();
+            for (; it != out.end (); ++it) {
+                dicIter->second.erase (find (dicIter->second.begin (),
+                                            dicIter->second.end (),
+                                            *it));
+            }
+        }
+        if (dicIter->second.empty ()) {
+            mDataItemsPerClientMap.erase (dicIter);
+            EXIT_LOG_WITH_ERROR ("%d",0);
+        }
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+template <typename CT, typename DIT>
+void ClientIndex <CT,DIT> :: add
+(
+    CT client,
+    const list <DIT> & l,
+    list <DIT> & out
+)
+{
+    ENTRY_LOG ();
+    list <DIT> difference;
+    typename map < CT, list <DIT> > :: iterator dicIter =
+        mDataItemsPerClientMap.find (client);
+    if (dicIter != mDataItemsPerClientMap.end ()) {
+        set_difference (l.begin (), l.end (),
+                       dicIter->second.begin (), dicIter->second.end (),
+                       inserter (difference,difference.begin ()));
+        if (!difference.empty ()) {
+            difference.sort ();
+            out = difference;
+            dicIter->second.merge (difference);
+            dicIter->second.unique ();
+        }
+    } else {
+        out = l;
+        pair < CT, list <DIT> > dicnpair (client, out);
+        mDataItemsPerClientMap.insert (dicnpair);
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+// Explicit instantiation must occur in same namespace where class is defined
+namespace loc_core
+{
+  template class ClientIndex <IDataItemObserver *, DataItemId>;
+  template class ClientIndex <string, DataItemId>;
+}
diff --git a/core/data-items/common/ClientIndex.h b/core/data-items/common/ClientIndex.h
new file mode 100644
index 0000000..feccb05
--- /dev/null
+++ b/core/data-items/common/ClientIndex.h
@@ -0,0 +1,70 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __CLIENTINDEX_H__
+#define __CLIENTINDEX_H__
+
+#include <list>
+#include <map>
+#include <IClientIndex.h>
+
+using loc_core::IClientIndex;
+
+namespace loc_core
+{
+
+template <typename CT, typename DIT>
+
+class ClientIndex : public IClientIndex  <CT, DIT> {
+
+public:
+
+    ClientIndex ();
+
+    ~ClientIndex ();
+
+    bool isSubscribedClient (CT client);
+
+    void getSubscribedList (CT client, std :: list <DIT> & out);
+
+    int remove (CT client);
+
+    void remove (const std :: list <DIT> & r, std :: list <CT> & out);
+
+    void remove (CT client, const std :: list <DIT> & r, std :: list <DIT> & out);
+
+    void add (CT client, const std :: list <DIT> & l, std :: list <DIT> & out);
+
+private:
+    //Data members
+    std :: map < CT , std :: list <DIT> > mDataItemsPerClientMap;
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __CLIENTINDEX_H__
diff --git a/core/data-items/common/DataItemIndex.cpp b/core/data-items/common/DataItemIndex.cpp
new file mode 100644
index 0000000..7869b43
--- /dev/null
+++ b/core/data-items/common/DataItemIndex.cpp
@@ -0,0 +1,202 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string>
+#include <algorithm>
+#include <iterator>
+#include <DataItemIndex.h>
+#include <platform_lib_log_util.h>
+#include <IDataItemObserver.h>
+#include <DataItemId.h>
+
+using namespace std;
+using namespace loc_core;
+
+template <typename CT, typename DIT>
+inline DataItemIndex <CT,DIT> :: DataItemIndex () {}
+
+template <typename CT, typename DIT>
+inline DataItemIndex <CT,DIT> :: ~DataItemIndex () {}
+
+template <typename CT, typename DIT>
+void DataItemIndex <CT,DIT> :: getListOfSubscribedClients
+ (
+    DIT id,
+    list <CT> & out
+)
+{
+    typename map < DIT, list <CT> > :: iterator cdiIter =
+        mClientsPerDataItemMap.find (id);
+    if (cdiIter != mClientsPerDataItemMap.end ()) {
+        out = cdiIter->second;
+    }
+}
+
+
+template <typename CT, typename DIT>
+int DataItemIndex <CT,DIT> :: remove (DIT id) {
+    int result = 0;
+    ENTRY_LOG ();
+    mClientsPerDataItemMap.erase (id);
+    EXIT_LOG_WITH_ERROR ("%d",result);
+    return result;
+}
+
+template <typename CT, typename DIT>
+void DataItemIndex <CT,DIT> :: remove (const list <CT> & r, list <DIT> & out) {
+    ENTRY_LOG ();
+    typename map < DIT, list <CT> > :: iterator cdiIter =
+        mClientsPerDataItemMap.begin ();
+    while (cdiIter != mClientsPerDataItemMap.end()) {
+        typename list <CT> :: const_iterator it = r.begin ();
+        for (; it != r.end (); ++it) {
+            typename list <CT> :: iterator iter =
+                find
+                (
+                    cdiIter->second.begin (),
+                    cdiIter->second.end (),
+                    *it
+                );
+            if (iter != cdiIter->second.end ()) {
+                cdiIter->second.erase (iter);
+            }
+        }
+
+        if (cdiIter->second.empty ()) {
+            out.push_back (cdiIter->first);
+            // Post-increment operator increases the iterator but returns the
+            // prevous one that will be invalidated by erase()
+            mClientsPerDataItemMap.erase (cdiIter++);
+        } else {
+            ++cdiIter;
+        }
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+template <typename CT, typename DIT>
+void DataItemIndex <CT,DIT> :: remove
+(
+    DIT id,
+    const list <CT> & r,
+    list <CT> & out
+)
+{
+    ENTRY_LOG ();
+
+    typename map < DIT, list <CT> > :: iterator cdiIter =
+        mClientsPerDataItemMap.find (id);
+    if (cdiIter != mClientsPerDataItemMap.end ()) {
+        set_intersection (cdiIter->second.begin (), cdiIter->second.end (),
+                         r.begin (), r.end (),
+                         inserter (out, out.begin ()));
+        if (!out.empty ()) {
+            typename list <CT> :: iterator it = out.begin ();
+            for (; it != out.end (); ++it) {
+                cdiIter->second.erase (find (cdiIter->second.begin (),
+                                            cdiIter->second.end (),
+                                            *it));
+            }
+        }
+        if (cdiIter->second.empty ()) {
+            mClientsPerDataItemMap.erase (cdiIter);
+            EXIT_LOG_WITH_ERROR ("%d",0);
+        }
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+template <typename CT, typename DIT>
+void DataItemIndex <CT,DIT> :: add
+(
+    DIT id,
+    const list <CT> & l,
+    list <CT> & out
+)
+{
+    ENTRY_LOG ();
+    list <CT> difference;
+    typename map < DIT, list <CT> > :: iterator cdiIter =
+        mClientsPerDataItemMap.find (id);
+    if (cdiIter != mClientsPerDataItemMap.end ()) {
+        set_difference (l.begin (), l.end (),
+                       cdiIter->second.begin (), cdiIter->second.end (),
+                       inserter (difference, difference.begin ()));
+        if (!difference.empty ()) {
+            difference.sort ();
+            out = difference;
+            cdiIter->second.merge (difference);
+        }
+    } else {
+        out = l;
+        pair < DIT, list <CT> > cndipair (id, out);
+        mClientsPerDataItemMap.insert (cndipair);
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+template <typename CT, typename DIT>
+void DataItemIndex <CT,DIT> :: add
+(
+    CT client,
+    const list <DIT> & l,
+    list <DIT> & out
+)
+{
+    ENTRY_LOG ();
+    typename map < DIT, list <CT> > :: iterator cdiIter;
+    typename list <DIT> :: const_iterator it = l.begin ();
+    for (; it != l.end (); ++it) {
+        cdiIter = mClientsPerDataItemMap.find (*it);
+        if (cdiIter == mClientsPerDataItemMap.end ()) {
+            out.push_back (*it);
+            pair < DIT, list <CT> > cndiPair (*it, list <CT> (1, client));
+            mClientsPerDataItemMap.insert (cndiPair);
+        } else {
+          typename list<CT> :: iterator clientIter =
+              find
+              (
+                cdiIter->second.begin (),
+                cdiIter->second.end (),
+                client
+              );
+            if (clientIter == cdiIter->second.end()) {
+              cdiIter->second.push_back (client);
+            }
+        }
+    }
+    EXIT_LOG_WITH_ERROR ("%d",0);
+}
+
+// Explicit instantiation must occur in same namespace where class is defined
+namespace loc_core
+{
+  template class DataItemIndex <IDataItemObserver *, DataItemId>;
+  template class DataItemIndex <string, DataItemId>;
+}
diff --git a/core/data-items/common/DataItemIndex.h b/core/data-items/common/DataItemIndex.h
new file mode 100644
index 0000000..d72e89e
--- /dev/null
+++ b/core/data-items/common/DataItemIndex.h
@@ -0,0 +1,70 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __DATAITEMINDEX_H__
+#define __DATAITEMINDEX_H__
+
+#include <list>
+#include <map>
+#include <IDataItemIndex.h>
+
+using loc_core::IDataItemIndex;
+
+namespace loc_core
+{
+
+template <typename CT, typename DIT>
+
+class DataItemIndex : public IDataItemIndex  <CT, DIT> {
+
+public:
+
+    DataItemIndex ();
+
+    ~DataItemIndex ();
+
+    void getListOfSubscribedClients (DIT id, std :: list <CT> & out);
+
+    int remove (DIT id);
+
+    void remove (const std :: list <CT> & r, std :: list <DIT> & out);
+
+    void remove (DIT id, const std :: list <CT> & r, std :: list <CT> & out);
+
+    void add (DIT id, const std :: list <CT> & l, std :: list <CT> & out);
+
+    void add (CT client, const std :: list <DIT> & l, std :: list <DIT> & out);
+
+private:
+    std :: map < DIT, std :: list <CT> > mClientsPerDataItemMap;
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __DATAITEMINDEX_H__
diff --git a/core/data-items/common/IClientIndex.h b/core/data-items/common/IClientIndex.h
new file mode 100644
index 0000000..0272e7b
--- /dev/null
+++ b/core/data-items/common/IClientIndex.h
@@ -0,0 +1,83 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ICLIENTINDEX_H__
+#define __ICLIENTINDEX_H__
+
+#include <list>
+
+namespace loc_core
+{
+
+template  <typename CT, typename DIT>
+
+class IClientIndex {
+public:
+
+    // Checks if client is subscribed
+    virtual bool isSubscribedClient (CT client) = 0;
+
+    // gets subscription list
+    virtual void getSubscribedList (CT client, std :: list <DIT> & out) = 0;
+
+    // removes an entry
+    virtual int remove (CT client) = 0;
+
+    // removes std :: list of data items and returns a list of clients
+    // removed if any.
+    virtual void remove
+    (
+        const std :: list <DIT> & r,
+        std :: list <CT> & out
+    ) = 0;
+
+    // removes list of data items indexed by client and returns list
+    // of data items removed if any.
+    virtual void remove
+    (
+        CT client,
+        const std :: list <DIT> & r,
+        std :: list <DIT> & out
+    ) = 0;
+
+    // adds/modifies entry in  map and returns new data items added.
+    virtual void add
+    (
+        CT client,
+        const std :: list <DIT> & l,
+        std :: list <DIT> & out
+    ) = 0;
+
+    // dtor
+    virtual ~IClientIndex () {}
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __ICLIENTINDEX_H__
diff --git a/core/data-items/common/IDataItemIndex.h b/core/data-items/common/IDataItemIndex.h
new file mode 100644
index 0000000..9185582
--- /dev/null
+++ b/core/data-items/common/IDataItemIndex.h
@@ -0,0 +1,94 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __IDATAITEMINDEX_H__
+#define __IDATAITEMINDEX_H__
+
+#include <list>
+
+namespace loc_core
+{
+
+template <typename CT, typename DIT>
+
+class IDataItemIndex {
+
+public:
+
+    // gets std :: list of subscribed clients
+    virtual void getListOfSubscribedClients
+    (
+        DIT id,
+        std :: list <CT> & out
+    ) = 0;
+
+    // removes an entry from
+    virtual int remove (DIT id) = 0;
+
+    // removes list of clients and returns a list of data items
+    // removed if any.
+    virtual void remove
+    (
+        const std :: list <CT> & r,
+        std :: list <DIT> & out
+    ) = 0;
+
+    // removes list of clients indexed by data item and returns list of
+    // clients removed if any.
+    virtual void remove
+    (
+        DIT id,
+        const std :: list <CT> & r,
+        std :: list <CT> & out
+    ) = 0;
+
+    // adds/modifies entry and returns new clients added
+    virtual void add
+    (
+        DIT id,
+        const std :: list <CT> & l,
+        std :: list <CT> & out
+    ) = 0;
+
+    // adds/modifies entry and returns yet to subscribe list of data items
+    virtual void add
+    (
+        CT client,
+        const std :: list <DIT> & l,
+        std :: list <DIT> & out
+    ) = 0;
+
+    // dtor
+    virtual ~IDataItemIndex () {}
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __IDATAITEMINDEX_H__
+
diff --git a/core/data-items/common/IndexFactory.cpp b/core/data-items/common/IndexFactory.cpp
new file mode 100644
index 0000000..cf49475
--- /dev/null
+++ b/core/data-items/common/IndexFactory.cpp
@@ -0,0 +1,64 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string>
+#include <IndexFactory.h>
+#include <IClientIndex.h>
+#include <ClientIndex.h>
+#include <IDataItemIndex.h>
+#include <DataItemIndex.h>
+#include <IDataItemObserver.h>
+#include <DataItemId.h>
+
+using namespace std;
+using loc_core::IClientIndex;
+using loc_core::IDataItemIndex;
+using loc_core::IDataItemObserver;
+using namespace loc_core;
+
+template <typename CT, typename DIT>
+inline IClientIndex <CT, DIT> * IndexFactory <CT, DIT> :: createClientIndex
+()
+{
+    return new (nothrow) ClientIndex <CT, DIT> ();
+}
+
+template <typename CT, typename DIT>
+inline IDataItemIndex <CT, DIT> * IndexFactory <CT, DIT> :: createDataItemIndex
+()
+{
+    return new (nothrow) DataItemIndex <CT, DIT> ();
+}
+
+// Explicit instantiation must occur in same namespace where class is defined
+namespace loc_core
+{
+  template class IndexFactory <IDataItemObserver *, DataItemId>;
+  template class IndexFactory <string, DataItemId>;
+}
diff --git a/core/data-items/common/IndexFactory.h b/core/data-items/common/IndexFactory.h
new file mode 100644
index 0000000..9a2070e
--- /dev/null
+++ b/core/data-items/common/IndexFactory.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __INDEXFACTORY_H__
+#define __INDEXFACTORY_H__
+
+#include <IClientIndex.h>
+#include <IDataItemIndex.h>
+
+namespace loc_core
+{
+template <typename CT, typename DIT>
+class IndexFactory {
+
+public:
+    static IClientIndex <CT, DIT> * createClientIndex ();
+    static IDataItemIndex <CT, DIT> * createDataItemIndex ();
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __INDEXFACTORY_H__
diff --git a/core/observer/IDataItemObserver.h b/core/observer/IDataItemObserver.h
new file mode 100644
index 0000000..7954d85
--- /dev/null
+++ b/core/observer/IDataItemObserver.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __IDATAITEMOBSERVER_H__
+#define __IDATAITEMOBSERVER_H__
+
+#include  <list>
+#include <string>
+
+using namespace std;
+
+namespace loc_core
+{
+class IDataItemCore;
+
+/**
+ * @brief IDataItemObserver interface
+ * @details IDataItemObserver interface;
+ *          In OS dependent code this type serves as a handle to an OS independent instance of this interface.
+ */
+class IDataItemObserver {
+
+public:
+
+    /**
+     * @brief Gets name of Data Item Observer
+     * @details Gets name of Data Item Observer
+     *
+     * @param name reference to name of Data Item Observer
+     */
+    virtual void getName (string & name) = 0;
+
+    /**
+     * @brief Notify updated values of Data Items
+     * @details Notifys updated values of Data items
+     *
+     * @param dlist List of updated data items
+     */
+    virtual void notify (const std :: list <IDataItemCore *> & dlist)  = 0;
+
+    /**
+     * @brief Destructor
+     * @details Destructor
+     */
+    virtual ~IDataItemObserver () {}
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __IDATAITEMOBSERVER_H__
diff --git a/core/observer/IDataItemSubscription.h b/core/observer/IDataItemSubscription.h
new file mode 100644
index 0000000..7e8b8c8
--- /dev/null
+++ b/core/observer/IDataItemSubscription.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __IDATAITEMSUBSCRIPTION_H__
+#define __IDATAITEMSUBSCRIPTION_H__
+
+#include  <list>
+#include  <DataItemId.h>
+
+namespace loc_core
+{
+class IDataItemObserver;
+
+/**
+ * @brief IDataItemSubscription interface
+ * @details IDataItemSubscription interface;
+ *          Defines an interface for operations such as subscribe,
+ *          unsubscribe data items by their IDs.
+ *          Must be implemented by OS dependent code.
+ */
+class IDataItemSubscription {
+
+public:
+    /**
+     * @brief Subscribe for data items by their IDs
+     * @details Subscribe for data items by their IDs;
+     *          An IDataItemObserver implementer invokes this method to subscribe
+     *          for a list of DataItems by passing in their Ids.
+     *          A symbolic invocation of this method in the following order
+     *          subscribe ( {1,2,3}, &obj), subscribe ( {2,3,4,5}, &obj)
+     *          where the numbers enclosed in braces indicate a list of data item Ids
+     *          will cause this class implementer to update its subscription list for
+     *          &obj to only contain the following Data Item Ids 1,2,3,4,5.
+     *
+     * @param l List of DataItemId
+     * @param o Pointer to an instance of IDataItemObserver
+     */
+    virtual void subscribe (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
+
+    /**
+     * @brief Update subscription for Data items
+     * @details Update subscription for Data items;
+     *          An IDataItemObserver implementer invokes this method to update their
+     *          subscription for a list of DataItems by passing in their Ids
+     *          A symbolic invocation of this method in the following order
+     *          updateSubscription ( {1,2,3}, &obj),updateSubscription ( {2,3,4,5}, &obj)
+     *          where the numbers enclosed in braces indicate a list of data item Ids
+     *          will cause this class implementer to update its subscription list for
+     *          &obj to only contain the following Data Item Ids 2,3,4,5.
+     *          Note that this method may or may not be called.
+     *
+     * @param l List of DataItemId
+     * @param o Pointer to an instance of IDataItemObserver
+     */
+    virtual void updateSubscription (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
+
+    /**
+     * @brief Request Data
+     * @details Request Data
+     *
+     * @param l List of DataItemId
+     * @param o Pointer to an instance of IDataItemObserver
+     */
+    virtual void requestData (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
+
+    /**
+     * @brief Unsubscribe Data items
+     * @details Unsubscrbe Data items;
+     *          An IDataItemObserver implementer invokes this method to unsubscribe their
+     *          subscription for a list of DataItems by passing in their Ids
+     *          Suppose this class implementor has a currently active subscription list
+     *          containing 1,2,3,4,5,6,7 for &obj then a symbolic invocation of this
+     *          method in the following order
+     *          unsubscribe ( {1,2,3}, &obj), unsubscribe (  {1,2,3,4}, &obj),
+     *          unsubscribe ( {7}, &obj)
+     *          where the numbers enclosed in braces indicate a list of data item Ids
+     *          will cause this class implementer to update its subscription list for
+     *          &obj to only contain the following data item id 5,6.
+     *
+     * @param l List of DataItemId
+     * @param o Pointer to an instance of IDataItemObserver
+     */
+    virtual void unsubscribe (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
+
+    /**
+     * @brief Unsubscribe all data items
+     * @details Unsubscribe all data items
+     *
+     * @param o Pointer to an instance of IDataItemObserver
+     */
+    virtual void unsubscribeAll (IDataItemObserver * o = NULL) = 0;
+
+    /**
+     * @brief Destructor
+     * @details Destructor
+     */
+    virtual ~IDataItemSubscription () {}
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __IDATAITEMSUBSCRIPTION_H__
+
diff --git a/core/observer/IFrameworkActionReq.h b/core/observer/IFrameworkActionReq.h
new file mode 100644
index 0000000..c7b3ebd
--- /dev/null
+++ b/core/observer/IFrameworkActionReq.h
@@ -0,0 +1,83 @@
+/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __IFRAMEWORKACTIONREQ_H__
+#define __IFRAMEWORKACTIONREQ_H__
+
+#include  <DataItemId.h>
+
+namespace loc_core
+{
+
+/**
+ * @brief IFrameworkActionReq interface
+ * @details IFrameworkActionReq interface;
+ *          Defines an interface for operations such as turnOn, turnOff a
+ *          framework module described by the data item. Framework module
+ *          could be bluetooth, wifi etc.
+ *          Must be implemented by OS dependent code.
+ *
+ */
+class IFrameworkActionReq {
+
+public:
+    /**
+     * @brief Turn on the framework module described by the data item.
+     * @details  Turn on the framework module described by the data item;
+     *          An IFrameworkActionReq implementer invokes this method to
+     *          turn on the framework module described by the data item.
+     *          Framework module could be bluetooth, wifi etc.
+     *
+     * @param dit DataItemId
+     * @param timeout Timeout after which to turn off the framework module.
+     */
+    virtual void turnOn (DataItemId dit, int timeOut = 0) = 0;
+
+    /**
+     * @brief Turn off the framework module described by the data item.
+     * @details  Turn off the framework module described by the data item;
+     *          An IFrameworkActionReq implementer invokes this method to
+     *          turn off the framework module described by the data item.
+     *          Framework module could be bluetooth, wifi etc.
+     *
+     * @param dit DataItemId
+     */
+    virtual void turnOff (DataItemId dit) = 0;
+
+    /**
+     * @brief Destructor
+     * @details Destructor
+     */
+    virtual ~IFrameworkActionReq () {}
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __IFRAMEWORKACTIONREQ_H__
+
diff --git a/core/observer/IOsObserver.h b/core/observer/IOsObserver.h
new file mode 100644
index 0000000..3db8a85
--- /dev/null
+++ b/core/observer/IOsObserver.h
@@ -0,0 +1,103 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __IOSOBSERVER_H__
+#define __IOSOBSERVER_H__
+
+#include  <list>
+#include <string>
+#include <IDataItemObserver.h>
+#include <IDataItemSubscription.h>
+#include <IFrameworkActionReq.h>
+
+using namespace std;
+
+namespace loc_core
+{
+
+/**
+ * @brief IOsObserver interface
+ * @details IOsObserver interface;
+ *          In OS dependent code this type serves as a handle to
+ *          an OS independent instance of this interface.
+ */
+class IOsObserver :
+                public IDataItemObserver,
+                public IDataItemSubscription,
+                public IFrameworkActionReq {
+
+public:
+
+    // To set the subscription object
+    virtual void setSubscriptionObj(IDataItemSubscription *subscriptionObj) = 0;
+
+    // To set the framework action request object
+    virtual void setFrameworkActionReqObj(IFrameworkActionReq *frameworkActionReqObj) = 0;
+
+    // IDataItemObserver Overrides
+    inline virtual void getName (string & /*name*/) {}
+    inline virtual void notify (const std::list <IDataItemCore *> & /*dlist*/) {}
+
+    // IDataItemSubscription Overrides
+    inline virtual void subscribe
+    (
+        const std :: list <DataItemId> & /*l*/,
+        IDataItemObserver * /*client*/
+    ){}
+    inline virtual void updateSubscription
+    (
+        const std :: list <DataItemId> & /*l*/,
+        IDataItemObserver * /*client*/
+    ){}
+    inline virtual void requestData
+    (
+        const std :: list <DataItemId> & /*l*/,
+        IDataItemObserver * /*client*/
+    ){}
+    inline virtual void unsubscribe
+    (
+        const std :: list <DataItemId> & /*l*/,
+        IDataItemObserver * /*client*/
+    ){}
+    inline virtual void unsubscribeAll (IDataItemObserver * /*client*/){}
+
+    // IFrameworkActionReq Overrides
+    inline virtual void turnOn (DataItemId /*dit*/, int /*timeOut*/){}
+    inline virtual void turnOff (DataItemId /*dit*/) {}
+
+    /**
+     * @brief Destructor
+     * @details Destructor
+     */
+    virtual ~IOsObserver () {}
+};
+
+} // namespace loc_core
+
+#endif // #ifndef __IOSOBSERVER_H__