code:
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#define LOG_TAG "LocSvc_SystemStatusOsObserver"

#include <algorithm>
#include <SystemStatus.h>
#include <SystemStatusOsObserver.h>
#include <IDataItemCore.h>
#include <DataItemsFactoryProxy.h>

namespace loc_core
{
template <typename CINT, typename COUT>
COUT SystemStatusOsObserver::containerTransfer(CINT& inContainer) {
    COUT outContainer = {};
    for (auto item : inContainer) {
        outContainer.insert(outContainer.begin(), item);
    }
    return outContainer;
}

SystemStatusOsObserver::~SystemStatusOsObserver() {
    // Close data-item library handle
    DataItemsFactoryProxy::closeDataItemLibraryHandle();

    // Destroy cache
    for (auto each : mDataItemCache) {
        if (nullptr != each.second) {
            delete each.second;
        }
    }

    mDataItemCache.clear();
}

void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj)
{
    struct SetSubsObj : public LocMsg {
        ObserverContext& mContext;
        IDataItemSubscription* mSubsObj;
        inline SetSubsObj(ObserverContext& context, IDataItemSubscription* subscriptionObj) :
                mContext(context), mSubsObj(subscriptionObj) {}
        void proc() const {
            LOC_LOGi("SetSubsObj::enter");
            mContext.mSubscriptionObj = mSubsObj;

            if (!mContext.mSSObserver->mDataItemToClients.empty()) {
                list<DataItemId> dis(
                        containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
                                mContext.mSSObserver->mDataItemToClients.getKeys()));
                mContext.mSubscriptionObj->subscribe(dis, mContext.mSSObserver);
                mContext.mSubscriptionObj->requestData(dis, mContext.mSSObserver);
            }
            LOC_LOGi("SetSubsObj::exit");
        }
    };

    if (nullptr == subscriptionObj) {
        LOC_LOGw("subscriptionObj is NULL");
    } else {
        mContext.mMsgTask->sendMsg(new SetSubsObj(mContext, subscriptionObj));
    }
}

/******************************************************************************
 IDataItemSubscription Overrides
******************************************************************************/
void SystemStatusOsObserver::subscribe(const list<DataItemId>& l, IDataItemObserver* client,
                                       bool toRequestData)
{
    struct HandleSubscribeReq : public LocMsg {
        inline HandleSubscribeReq(SystemStatusOsObserver* parent,
                list<DataItemId>& l, IDataItemObserver* client, bool requestData) :
                mParent(parent), mClient(client),
                mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)),
                diItemlist(l),
                mToRequestData(requestData) {}

        void proc() const {
            unordered_set<DataItemId> dataItemsToSubscribe = {};
            mParent->mDataItemToClients.add(mDataItemSet, {mClient}, &dataItemsToSubscribe);
            mParent->mClientToDataItems.add(mClient, mDataItemSet);

            mParent->sendCachedDataItems(mDataItemSet, mClient);

            // Send subscription set to framework
            if (nullptr != mParent->mContext.mSubscriptionObj) {
                if (mToRequestData) {
                    LOC_LOGD("Request Data sent to framework for the following");
                    mParent->mContext.mSubscriptionObj->requestData(diItemlist, mParent);
                } else if (!dataItemsToSubscribe.empty()) {
                    LOC_LOGD("Subscribe Request sent to framework for the following");
                    mParent->logMe(dataItemsToSubscribe);
                    mParent->mContext.mSubscriptionObj->subscribe(
                            containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
                                    std::move(dataItemsToSubscribe)),
                            mParent);
                }
            }
        }
        mutable SystemStatusOsObserver* mParent;
        IDataItemObserver* mClient;
        const unordered_set<DataItemId> mDataItemSet;
        const list<DataItemId> diItemlist;
        bool mToRequestData;
    };

    if (l.empty() || nullptr == client) {
        LOC_LOGw("Data item set is empty or client is nullptr");
    } else {
        mContext.mMsgTask->sendMsg(
                new HandleSubscribeReq(this, (list<DataItemId>&)l, client, toRequestData));
    }
}

void SystemStatusOsObserver::updateSubscription(
        const list<DataItemId>& l, IDataItemObserver* client)
{
    struct HandleUpdateSubscriptionReq : public LocMsg {
        HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent,
                                    list<DataItemId>& l, IDataItemObserver* client) :
                mParent(parent), mClient(client),
                mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {}

        void proc() const {
            unordered_set<DataItemId> dataItemsToSubscribe = {};
            unordered_set<DataItemId> dataItemsToUnsubscribe = {};
            unordered_set<IDataItemObserver*> clients({mClient});
            // below removes clients from all entries keyed with the return of the
            // mClientToDataItems.update() call. If leaving an empty set of clients as the
            // result, the entire entry will be removed. dataItemsToUnsubscribe will be
            // populated to keep the keys of the removed entries.
            mParent->mDataItemToClients.trimOrRemove(
                    // this call updates <IDataItemObserver*, DataItemId> map; removes
                    // the DataItemId's that are not new to the clietn from mDataItemSet;
                    // and returns a set of mDataItemSet's that are no longer used by client.
                    // This unused set of mDataItemSet's is passed to trimOrRemove method of
                    // <DataItemId, IDataItemObserver*> map to remove the client from the
                    // corresponding entries, and gets a set of the entries that are
                    // removed from the <DataItemId, IDataItemObserver*> map as a result.
                    mParent->mClientToDataItems.update(mClient,
                                                       (unordered_set<DataItemId>&)mDataItemSet),
                    clients, &dataItemsToUnsubscribe, nullptr);
            // below adds mClient to <DataItemId, IDataItemObserver*> map, and populates
            // new keys added to that map, which are DataItemIds to be subscribed.
            mParent->mDataItemToClients.add(mDataItemSet, clients, &dataItemsToSubscribe);

            // Send First Response
            mParent->sendCachedDataItems(mDataItemSet, mClient);

            if (nullptr != mParent->mContext.mSubscriptionObj) {
                // Send subscription set to framework
                if (!dataItemsToSubscribe.empty()) {
                    LOC_LOGD("Subscribe Request sent to framework for the following");
                    mParent->logMe(dataItemsToSubscribe);

                    mParent->mContext.mSubscriptionObj->subscribe(
                            containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
                                    std::move(dataItemsToSubscribe)),
                            mParent);
                }

                // Send unsubscribe to framework
                if (!dataItemsToUnsubscribe.empty()) {
                    LOC_LOGD("Unsubscribe Request sent to framework for the following");
                    mParent->logMe(dataItemsToUnsubscribe);

                    mParent->mContext.mSubscriptionObj->unsubscribe(
                            containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
                                    std::move(dataItemsToUnsubscribe)),
                            mParent);
                }
            }
        }
        SystemStatusOsObserver* mParent;
        IDataItemObserver* mClient;
        unordered_set<DataItemId> mDataItemSet;
    };

    if (l.empty() || nullptr == client) {
        LOC_LOGw("Data item set is empty or client is nullptr");
    } else {
        mContext.mMsgTask->sendMsg(
                new HandleUpdateSubscriptionReq(this, (list<DataItemId>&)l, client));
    }
}

void SystemStatusOsObserver::unsubscribe(
        const list<DataItemId>& l, IDataItemObserver* client)
{
    struct HandleUnsubscribeReq : public LocMsg {
        HandleUnsubscribeReq(SystemStatusOsObserver* parent,
                list<DataItemId>& l, IDataItemObserver* client) :
                mParent(parent), mClient(client),
                mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {}

        void proc() const {
            unordered_set<DataItemId> dataItemsUnusedByClient = {};
            unordered_set<IDataItemObserver*> clientToRemove = {};
            unordered_set<DataItemId> dataItemsToUnsubscribe = {};
            mParent->mClientToDataItems.trimOrRemove({mClient}, mDataItemSet,  &clientToRemove,
                                                     &dataItemsUnusedByClient);
            mParent->mDataItemToClients.trimOrRemove(dataItemsUnusedByClient, {mClient},
                                                     &dataItemsToUnsubscribe, nullptr);

            if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToUnsubscribe.empty()) {
                LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
                mParent->logMe(dataItemsToUnsubscribe);

                // Send unsubscribe to framework
                mParent->mContext.mSubscriptionObj->unsubscribe(
                        containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
                                  std::move(dataItemsToUnsubscribe)),
                        mParent);
            }
        }
        SystemStatusOsObserver* mParent;
        IDataItemObserver* mClient;
        unordered_set<DataItemId> mDataItemSet;
    };

    if (l.empty() || nullptr == client) {
        LOC_LOGw("Data item set is empty or client is nullptr");
    } else {
        mContext.mMsgTask->sendMsg(new HandleUnsubscribeReq(this, (list<DataItemId>&)l, client));
    }
}

void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client)
{
    struct HandleUnsubscribeAllReq : public LocMsg {
        HandleUnsubscribeAllReq(SystemStatusOsObserver* parent,
                IDataItemObserver* client) :
                mParent(parent), mClient(client) {}

        void proc() const {
            unordered_set<DataItemId> diByClient = mParent->mClientToDataItems.getValSet(mClient);

            if (!diByClient.empty()) {
                unordered_set<DataItemId> dataItemsToUnsubscribe;
                mParent->mClientToDataItems.remove(mClient);
                mParent->mDataItemToClients.trimOrRemove(diByClient, {mClient},
                                                         &dataItemsToUnsubscribe, nullptr);

                if (!dataItemsToUnsubscribe.empty() &&
                    nullptr != mParent->mContext.mSubscriptionObj) {

                    LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
                    mParent->logMe(dataItemsToUnsubscribe);

                    // Send unsubscribe to framework
                    mParent->mContext.mSubscriptionObj->unsubscribe(
                            containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
                                    std::move(dataItemsToUnsubscribe)),
                            mParent);
                }
            }
        }
        SystemStatusOsObserver* mParent;
        IDataItemObserver* mClient;
    };

    if (nullptr == client) {
        LOC_LOGw("Data item set is empty or client is nullptr");
    } else {
        mContext.mMsgTask->sendMsg(new HandleUnsubscribeAllReq(this, client));
    }
}

/******************************************************************************
 IDataItemObserver Overrides
******************************************************************************/
void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist)
{
    struct HandleNotify : public LocMsg {
        HandleNotify(SystemStatusOsObserver* parent, vector<IDataItemCore*>& v) :
                mParent(parent), mDiVec(std::move(v)) {}

        inline virtual ~HandleNotify() {
            for (auto item : mDiVec) {
                delete item;
            }
        }

        void proc() const {
            // Update Cache with received data items and prepare
            // list of data items to be sent.
            unordered_set<DataItemId> dataItemIdsToBeSent = {};
            for (auto item : mDiVec) {
                if (mParent->updateCache(item)) {
                    dataItemIdsToBeSent.insert(item->getId());
                }
            }

            // Send data item to all subscribed clients
            unordered_set<IDataItemObserver*> clientSet = {};
            for (auto each : dataItemIdsToBeSent) {
                auto clients = mParent->mDataItemToClients.getValSetPtr(each);
                if (nullptr != clients) {
                    clientSet.insert(clients->begin(), clients->end());
                }
            }

            for (auto client : clientSet) {
                unordered_set<DataItemId> dataItemIdsForThisClient(
                        mParent->mClientToDataItems.getValSet(client));
                for (auto itr = dataItemIdsForThisClient.begin();
                        itr != dataItemIdsForThisClient.end(); ) {
                    if (dataItemIdsToBeSent.find(*itr) == dataItemIdsToBeSent.end()) {
                        itr = dataItemIdsForThisClient.erase(itr);
                    } else {
                        itr++;
                    }
                }

                mParent->sendCachedDataItems(dataItemIdsForThisClient, client);
            }
        }
        SystemStatusOsObserver* mParent;
        const vector<IDataItemCore*> mDiVec;
    };

    if (!dlist.empty()) {
        vector<IDataItemCore*> dataItemVec(dlist.size());

        for (auto each : dlist) {

            IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
            if (nullptr == di) {
                LOC_LOGw("Unable to create dataitem:%d", each->getId());
                continue;
            }

            // Copy contents into the newly created data item
            di->copy(each);

            // add this dataitem if updated from last one
            dataItemVec.push_back(di);
            IF_LOC_LOGD {
                string dv;
                di->stringify(dv);
                LOC_LOGd("notify: DataItem In Value:%s", dv.c_str());
            }
        }

        if (!dataItemVec.empty()) {
            mContext.mMsgTask->sendMsg(new HandleNotify(this, dataItemVec));
        }
    }
}

/******************************************************************************
 IFrameworkActionReq Overrides
******************************************************************************/
void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
{
    if (nullptr == mContext.mFrameworkActionReqObj) {
        LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
        return;
    }

    // Check if data item exists in mActiveRequestCount
    DataItemIdToInt::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
        struct HandleTurnOnMsg : public LocMsg {
            HandleTurnOnMsg(IFrameworkActionReq* framework,
                    DataItemId dit, int timeOut) :
                    mFrameworkActionReqObj(framework), mDataItemId(dit), mTimeOut(timeOut) {}
            virtual ~HandleTurnOnMsg() {}
            void proc() const {
                mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut);
            }
            IFrameworkActionReq* mFrameworkActionReqObj;
            DataItemId mDataItemId;
            int mTimeOut;
        };
        mContext.mMsgTask->sendMsg(
                new (nothrow) HandleTurnOnMsg(mContext.mFrameworkActionReqObj, dit, timeOut));
    }
    else {
        // Found in map, update reference count
        citer->second++;
        LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second);
    }
}

void SystemStatusOsObserver::turnOff(DataItemId dit)
{
    if (nullptr == mContext.mFrameworkActionReqObj) {
        LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
        return;
    }

    // Check if data item exists in mActiveRequestCount
    DataItemIdToInt::iterator citer = mActiveRequestCount.find(dit);
    if (citer != mActiveRequestCount.end()) {
        // found
        citer->second--;
        LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second);
        if(citer->second == 0) {
            // if this was last reference, remove item from map and turn off module
            mActiveRequestCount.erase(citer);

            // Send action turn off to framework
            struct HandleTurnOffMsg : public LocMsg {
                HandleTurnOffMsg(IFrameworkActionReq* framework, DataItemId dit) :
                    mFrameworkActionReqObj(framework), mDataItemId(dit) {}
                virtual ~HandleTurnOffMsg() {}
                void proc() const {
                    mFrameworkActionReqObj->turnOff(mDataItemId);
                }
                IFrameworkActionReq* mFrameworkActionReqObj;
                DataItemId mDataItemId;
            };
            mContext.mMsgTask->sendMsg(
                    new (nothrow) HandleTurnOffMsg(mContext.mFrameworkActionReqObj, dit));
        }
    }
}

#ifdef USE_GLIB
bool SystemStatusOsObserver::connectBackhaul(const string& clientName)
{
    bool result = false;

    if (mContext.mFrameworkActionReqObj != NULL) {
        struct HandleConnectBackhaul : public LocMsg {
            HandleConnectBackhaul(IFrameworkActionReq* fwkActReq, const string& clientName) :
                    mClientName(clientName), mFwkActionReqObj(fwkActReq) {}
            virtual ~HandleConnectBackhaul() {}
            void proc() const {
                LOC_LOGi("HandleConnectBackhaul::enter");
                mFwkActionReqObj->connectBackhaul(mClientName);
                LOC_LOGi("HandleConnectBackhaul::exit");
            }
            IFrameworkActionReq* mFwkActionReqObj;
            string mClientName;
        };
        mContext.mMsgTask->sendMsg(
                new (nothrow) HandleConnectBackhaul(mContext.mFrameworkActionReqObj, clientName));
        result = true;
    }
    else {
        LOC_LOGe("Framework action request object is NULL.Caching connect request: %s",
                clientName.c_str());
        ClientBackhaulReqCache::const_iterator iter = mBackHaulConnReqCache.find(clientName);
        if (iter == mBackHaulConnReqCache.end()) {
            // not found in set. first time receiving from request from client
            LOC_LOGe("Adding client to BackHaulConnReqCache list");
            mBackHaulConnReqCache.insert(clientName);
        }
        result = false;
    }
    return result;

}

bool SystemStatusOsObserver::disconnectBackhaul(const string& clientName)
{
    bool result = false;

    if (mContext.mFrameworkActionReqObj != NULL) {
        struct HandleDisconnectBackhaul : public LocMsg {
            HandleDisconnectBackhaul(IFrameworkActionReq* fwkActReq, const string& clientName) :
                    mClientName(clientName), mFwkActionReqObj(fwkActReq) {}
            virtual ~HandleDisconnectBackhaul() {}
            void proc() const {
                LOC_LOGi("HandleDisconnectBackhaul::enter");
                mFwkActionReqObj->disconnectBackhaul(mClientName);
                LOC_LOGi("HandleDisconnectBackhaul::exit");
            }
            IFrameworkActionReq* mFwkActionReqObj;
            string mClientName;
        };
        mContext.mMsgTask->sendMsg(
                new (nothrow) HandleDisconnectBackhaul(mContext.mFrameworkActionReqObj,
                        clientName));
    }
    else {
        LOC_LOGe("Framework action request object is NULL.Caching disconnect request: %s",
                clientName.c_str());
        // Check if client has requested for backhaul connection.
        ClientBackhaulReqCache::const_iterator iter = mBackHaulConnReqCache.find(clientName);
        if (iter != mBackHaulConnReqCache.end()) {
            // client found, remove from set.
            LOC_LOGd("Removing client from BackHaulConnReqCache list");
            mBackHaulConnReqCache.erase(iter);
        }
        result = false;
    }
    return result;
}
#endif
/******************************************************************************
 Helpers
******************************************************************************/
void SystemStatusOsObserver::sendCachedDataItems(
        const unordered_set<DataItemId>& s, IDataItemObserver* to)
{
    if (nullptr == to) {
        LOC_LOGv("client pointer is NULL.");
    } else {
        string clientName;
        to->getName(clientName);
        list<IDataItemCore*> dataItems = {};

        for (auto each : s) {
            auto citer = mDataItemCache.find(each);
            if (citer != mDataItemCache.end()) {
                string dv;
                citer->second->stringify(dv);
                LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
                dataItems.push_front(citer->second);
            }
        }

        if (dataItems.empty()) {
            LOC_LOGv("No items to notify.");
        } else {
            to->notify(dataItems);
        }
    }
}

bool SystemStatusOsObserver::updateCache(IDataItemCore* d)
{
    bool dataItemUpdated = false;

    // Request systemstatus to record this dataitem in its cache
    // if the return is false, it means that SystemStatus is not
    // handling it, so SystemStatusOsObserver also doesn't.
    // So it has to be true to proceed.
    if (nullptr != d && mSystemStatus->eventDataItemNotify(d)) {
        auto citer = mDataItemCache.find(d->getId());
        if (citer == mDataItemCache.end()) {
            // New data item; not found in cache
            IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
            if (nullptr != dataitem) {
                // Copy the contents of the data item
                dataitem->copy(d);
                // Insert in mDataItemCache
                mDataItemCache.insert(std::make_pair(d->getId(), dataitem));
                dataItemUpdated = true;
            }
        } else {
            // Found in cache; Update cache if necessary
            citer->second->copy(d, &dataItemUpdated);
        }

        if (dataItemUpdated) {
            LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
        }
    }

    return dataItemUpdated;
}

} // namespace loc_core


code:
/* Copyright (c) 2015-2017, 2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#ifndef __SYSTEM_STATUS_OSOBSERVER__
#define __SYSTEM_STATUS_OSOBSERVER__

#include <cinttypes>
#include <string>
#include <list>
#include <map>
#include <new>
#include <vector>

#include <MsgTask.h>
#include <DataItemId.h>
#include <IOsObserver.h>
#include <loc_pla.h>
#include <log_util.h>
#include <LocUnorderedSetMap.h>

namespace loc_core
{
/******************************************************************************
 SystemStatusOsObserver
******************************************************************************/
using namespace std;
using namespace loc_util;

// Forward Declarations
class IDataItemCore;
class SystemStatus;
class SystemStatusOsObserver;
typedef map<IDataItemObserver*, list<DataItemId>> ObserverReqCache;
typedef LocUnorderedSetMap<IDataItemObserver*, DataItemId> ClientToDataItems;
typedef LocUnorderedSetMap<DataItemId, IDataItemObserver*> DataItemToClients;
typedef unordered_map<DataItemId, IDataItemCore*> DataItemIdToCore;
typedef unordered_map<DataItemId, int> DataItemIdToInt;
#ifdef USE_GLIB
// Cache details of backhaul client requests
typedef unordered_set<string> ClientBackhaulReqCache;
#endif

struct ObserverContext {
    IDataItemSubscription* mSubscriptionObj;
    IFrameworkActionReq* mFrameworkActionReqObj;
    const MsgTask* mMsgTask;
    SystemStatusOsObserver* mSSObserver;

    inline ObserverContext(const MsgTask* msgTask, SystemStatusOsObserver* observer) :
            mSubscriptionObj(NULL), mFrameworkActionReqObj(NULL),
            mMsgTask(msgTask), mSSObserver(observer) {}
};

// 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
    inline SystemStatusOsObserver(SystemStatus* systemstatus, const MsgTask* msgTask) :
            mSystemStatus(systemstatus), mContext(msgTask, this),
            mAddress("SystemStatusOsObserver"),
            mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID) {}

    // dtor
    ~SystemStatusOsObserver();

    template <typename CINT, typename COUT>
    static COUT containerTransfer(CINT& s);
    template <typename CINT, typename COUT>
    inline static COUT containerTransfer(CINT&& s) {
        return containerTransfer<CINT, COUT>(s);
    }

    // To set the subscription object
    virtual void setSubscriptionObj(IDataItemSubscription* subscriptionObj);

    // To set the framework action request object
    inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) {
        mContext.mFrameworkActionReqObj = frameworkActionReqObj;
#ifdef USE_GLIB
        uint32_t numBackHaulClients = mBackHaulConnReqCache.size();
        if (numBackHaulClients > 0) {
            // For each client, invoke connectbackhaul.
            for (auto clientName : mBackHaulConnReqCache) {
                LOC_LOGd("Invoke connectBackhaul for client: %s", clientName.c_str());
                connectBackhaul(clientName);
            }
            // Clear the set
            mBackHaulConnReqCache.clear();
        }
#endif
    }

    // IDataItemSubscription Overrides
    inline virtual void subscribe(const list<DataItemId>& l, IDataItemObserver* client) override {
        subscribe(l, client, false);
    }
    virtual void updateSubscription(const list<DataItemId>& l, IDataItemObserver* client) override;
    inline virtual void requestData(const list<DataItemId>& l, IDataItemObserver* client) override {
        subscribe(l, client, true);
    }
    virtual void unsubscribe(const list<DataItemId>& l, IDataItemObserver* client) override;
    virtual void unsubscribeAll(IDataItemObserver* client) override;

    // IDataItemObserver Overrides
    virtual void notify(const list<IDataItemCore*>& dlist) override;
    inline virtual void getName(string& name) override {
        name = mAddress;
    }

    // IFrameworkActionReq Overrides
    virtual void turnOn(DataItemId dit, int timeOut = 0) override;
    virtual void turnOff(DataItemId dit) override;
#ifdef USE_GLIB
    virtual bool connectBackhaul(const string& clientName) override;
    virtual bool disconnectBackhaul(const string& clientName) override;
#endif

private:
    SystemStatus*                                    mSystemStatus;
    ObserverContext                                  mContext;
    const string                                     mAddress;
    ClientToDataItems                                mClientToDataItems;
    DataItemToClients                                mDataItemToClients;
    DataItemIdToCore                                 mDataItemCache;
    DataItemIdToInt                                  mActiveRequestCount;

    // Cache the subscribe and requestData till subscription obj is obtained
    void cacheObserverRequest(ObserverReqCache& reqCache,
            const list<DataItemId>& l, IDataItemObserver* client);
#ifdef USE_GLIB
    // Cache the framework action request for connect/disconnect
    ClientBackhaulReqCache  mBackHaulConnReqCache;
#endif

    void subscribe(const list<DataItemId>& l, IDataItemObserver* client, bool toRequestData);

    // Helpers
    void sendCachedDataItems(const unordered_set<DataItemId>& s, IDataItemObserver* to);
    bool updateCache(IDataItemCore* d);
    inline void logMe(const unordered_set<DataItemId>& l) {
        IF_LOC_LOGD {
            for (auto id : l) {
                LOC_LOGD("DataItem %d", id);
            }
        }
    }
};

} // namespace loc_core

#endif //__SYSTEM_STATUS__

license: unknown


code:
# configure.ac -- Autoconf script for gps loc-core
#
# Process this file with autoconf to produce a configure script

# Requires autoconf tool later than 2.61
AC_PREREQ(2.61)
# Initialize the gps loc-hal package version 1.0.0
AC_INIT([loc-core],1.0.0)
# Does not strictly follow GNU Coding standards
AM_INIT_AUTOMAKE([foreign subdir-objects])
# Disables auto rebuilding of configure, Makefile.ins
AM_MAINTAINER_MODE
# Verifies the --srcdir is correct by checking for the path
AC_CONFIG_SRCDIR([loc-core.pc.in])
# defines some macros variable to be included by source
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])

# Checks for programs.
AC_PROG_LIBTOOL
AC_PROG_CXX
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_AWK
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG

# Checks for libraries.
PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
AC_SUBST([GPSUTILS_CFLAGS])
AC_SUBST([GPSUTILS_LIBS])

AC_ARG_WITH([core_includes],
      AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
         [Specify the location of the core headers]),
      [core_incdir=$withval],
      with_core_includes=no)

if test "x$with_core_includes" != "xno"; then
   CPPFLAGS="${CPPFLAGS} -I${core_incdir}"
fi

AC_ARG_WITH([locpla_includes],
      AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
         [specify the path to locpla-includes in loc-pla_git.bb]),
      [locpla_incdir=$withval],
      with_locpla_includes=no)

if test "x$with_locpla_includes" != "xno"; then
   AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
fi

AC_SUBST([CPPFLAGS])

AC_ARG_WITH([glib],
      AC_HELP_STRING([--with-glib],
         [enable glib, building HLOS systems which use glib]))

if (test "x${with_glib}" = "xyes"); then
        AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
        PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
                                AC_MSG_ERROR(GThread >= 2.16 is required))
        PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
                                AC_MSG_ERROR(GLib >= 2.16 is required))
        GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
        GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"

        AC_SUBST(GLIB_CFLAGS)
        AC_SUBST(GLIB_LIBS)
fi

AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")

AC_ARG_WITH([auto_feature],
    AC_HELP_STRING([--with-auto_feature=@<:@dir@:>@],
        [Using Automotive feature]),
    [],
    with_auto_feature=no)

if test "x$with_auto_feature" != "xno"; then
    CPPFLAGS="${CPPFLAGS} -DFEATURE_AUTOMOTIVE"
fi

AM_CONDITIONAL(USE_FEATURE_AUTOMOTIVE, test "x${with_auto_feature}" = "xyes")

# External AP
AC_ARG_WITH([external_ap],
    AC_HELP_STRING([--with-external_ap=@<:@dir@:>@],
        [Using External Application Processor]),
    [],
    with_external_ap=no)

if test "x$with_external_ap" != "xno"; then
    CPPFLAGS="${CPPFLAGS} -DFEATURE_EXTERNAL_AP"
fi

AM_CONDITIONAL(USE_EXTERNAL_AP, test "x${with_external_ap}" = "xyes")

AC_CONFIG_FILES([ \
        Makefile \
        loc-core.pc \
        ])

AC_OUTPUT


code:
/* Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef __DATAITEMCONCRETEBASETYPES__
#define __DATAITEMCONCRETEBASETYPES__

#include <string>
#include <cstring>
#include <sstream>
#include <DataItemId.h>
#include <IDataItemCore.h>
#include <gps_extended_c.h>
#include <inttypes.h>

#define MAC_ADDRESS_LENGTH    6
// MAC address length in bytes
// QMI_LOC_SRN_MAC_ADDR_LENGTH_V02
#define SRN_MAC_ADDRESS_LENGTH    6
#define WIFI_SUPPLICANT_DEFAULT_STATE    0

static constexpr char sDelimit = ':';

namespace loc_core
{
using namespace std;

enum NetworkType {
    TYPE_MOBILE = 0,
    TYPE_WIFI,
    TYPE_ETHERNET,
    TYPE_BLUETOOTH,
    TYPE_MMS,
    TYPE_SUPL,
    TYPE_DUN,
    TYPE_HIPRI,
    TYPE_WIMAX,
    TYPE_PROXY,
    TYPE_UNKNOWN,
};

typedef struct NetworkInfoType
{
    // Unique network handle ID
    uint64_t networkHandle;
    // Type of network for corresponding network handle
    NetworkType networkType;
    NetworkInfoType() : networkHandle(NETWORK_HANDLE_UNKNOWN), networkType(TYPE_UNKNOWN) {}
    NetworkInfoType(string strObj) {
        size_t posDelimit = strObj.find(sDelimit);

        if ( posDelimit != string::npos) {
            int32_t type = TYPE_UNKNOWN;
            string handleStr = strObj.substr(0, posDelimit);
            string typeStr = strObj.substr(posDelimit + 1, strObj.length() - posDelimit - 1);
            stringstream(handleStr) >> networkHandle;
            stringstream(typeStr) >> type;
            networkType = (NetworkType) type;
        } else {
            networkHandle = NETWORK_HANDLE_UNKNOWN;
            networkType = TYPE_UNKNOWN;
        }
    }
    bool operator== (const NetworkInfoType& other) {
        return ((networkHandle == other.networkHandle) && (networkType == other.networkType));
    }
    string toString() {
        string valueStr;
        valueStr.clear ();
        char nethandle [32];
        memset (nethandle, 0, 32);
        snprintf(nethandle, sizeof(nethandle), "%" PRIu64, networkHandle);
        valueStr += string(nethandle);
        valueStr += sDelimit;
        char type [12];
        memset (type, 0, 12);
        snprintf (type, 12, "%u", networkType);
        valueStr += string (type);
        return valueStr;
    }
} NetworkInfoType;

class AirplaneModeDataItemBase : public IDataItemCore  {
public:
    AirplaneModeDataItemBase(bool mode):
        mMode(mode),
        mId(AIRPLANEMODE_DATA_ITEM_ID) {}
    virtual ~AirplaneModeDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mMode;

protected:
    DataItemId mId;
};

class ENHDataItemBase : public IDataItemCore {
public:
    ENHDataItemBase(bool enabled) :
        mEnabled(enabled),
        mId(ENH_DATA_ITEM_ID) {}
    virtual ~ENHDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mEnabled;
protected:
    DataItemId mId;
};

class GPSStateDataItemBase : public IDataItemCore {
public:
    GPSStateDataItemBase(bool enabled) :
        mEnabled(enabled),
        mId(GPSSTATE_DATA_ITEM_ID) {}
    virtual ~GPSStateDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mEnabled;
protected:
    DataItemId mId;
};

class NLPStatusDataItemBase : public IDataItemCore {
public:
    NLPStatusDataItemBase(bool enabled) :
        mEnabled(enabled),
        mId(NLPSTATUS_DATA_ITEM_ID) {}
    virtual ~NLPStatusDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mEnabled;
protected:
    DataItemId mId;
};

class WifiHardwareStateDataItemBase : public IDataItemCore {
public:
    WifiHardwareStateDataItemBase(bool enabled) :
        mEnabled(enabled),
        mId(WIFIHARDWARESTATE_DATA_ITEM_ID) {}
    virtual ~WifiHardwareStateDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mEnabled;
protected:
    DataItemId mId;
};

class ScreenStateDataItemBase : public IDataItemCore {
public:
    ScreenStateDataItemBase(bool state) :
        mState(state),
        mId(SCREEN_STATE_DATA_ITEM_ID) {}
    virtual ~ScreenStateDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mState;
protected:
    DataItemId mId;
};

class PowerConnectStateDataItemBase : public IDataItemCore {
public:
    PowerConnectStateDataItemBase(bool state) :
        mState(state),
        mId(POWER_CONNECTED_STATE_DATA_ITEM_ID) {}
    virtual ~PowerConnectStateDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mState;
protected:
    DataItemId mId;
};

class TimeZoneChangeDataItemBase : public IDataItemCore {
public:
    TimeZoneChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) :
        mCurrTimeMillis (currTimeMillis),
        mRawOffsetTZ (rawOffset),
        mDstOffsetTZ (dstOffset),
        mId(TIMEZONE_CHANGE_DATA_ITEM_ID) {}
    virtual ~TimeZoneChangeDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    int64_t mCurrTimeMillis;
    int32_t mRawOffsetTZ;
    int32_t mDstOffsetTZ;
protected:
    DataItemId mId;
};

class TimeChangeDataItemBase : public IDataItemCore {
public:
    TimeChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) :
        mCurrTimeMillis (currTimeMillis),
        mRawOffsetTZ (rawOffset),
        mDstOffsetTZ (dstOffset),
        mId(TIME_CHANGE_DATA_ITEM_ID) {}
    virtual ~TimeChangeDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    int64_t mCurrTimeMillis;
    int32_t mRawOffsetTZ;
    int32_t mDstOffsetTZ;
protected:
    DataItemId mId;
};

class ShutdownStateDataItemBase : public IDataItemCore {
public:
    ShutdownStateDataItemBase(bool state) :
        mState (state),
        mId(SHUTDOWN_STATE_DATA_ITEM_ID) {}
    virtual ~ShutdownStateDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mState;
protected:
    DataItemId mId;
};

class AssistedGpsDataItemBase : public IDataItemCore {
public:
    AssistedGpsDataItemBase(bool enabled) :
        mEnabled(enabled),
        mId(ASSISTED_GPS_DATA_ITEM_ID) {}
    virtual ~AssistedGpsDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    bool mEnabled;
protected:
    DataItemId mId;
};

class NetworkInfoDataItemBase : public IDataItemCore {
public:
    NetworkInfoDataItemBase(
    NetworkType initialType, int32_t type, string typeName, string subTypeName,
    bool available, bool connected, bool roaming, uint64_t networkHandle, string apn):
            mAllTypes(typeToAllTypes(initialType)),
            mType(type),
            mTypeName(typeName),
            mSubTypeName(subTypeName),
            mAvailable(available),
            mConnected(connected),
            mRoaming(roaming),
            mNetworkHandle(networkHandle),
            mId(NETWORKINFO_DATA_ITEM_ID), mApn(apn) {
                mAllNetworkHandles[0].networkHandle = networkHandle;
                mAllNetworkHandles[0].networkType = initialType;
            }
    virtual ~NetworkInfoDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
    inline virtual NetworkType getType(void) const {
        return (NetworkType)mType;
    }
    inline uint64_t getAllTypes() { return mAllTypes; }
    inline NetworkInfoType* getNetworkHandle() {
        return &mAllNetworkHandles[0];
    }
    // Data members
    uint64_t mAllTypes;
    int32_t mType;
    string mTypeName;
    string mSubTypeName;
    bool mAvailable;
    bool mConnected;
    bool mRoaming;
    NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES];
    uint64_t mNetworkHandle;
    string mApn;
protected:
    DataItemId mId;
    inline uint64_t typeToAllTypes(NetworkType type) {
        return (type >= TYPE_UNKNOWN || type < TYPE_MOBILE) ?  0 : (1<<type);
    }
};

class ServiceStatusDataItemBase : public IDataItemCore {
public:
    ServiceStatusDataItemBase(int32_t serviceState) :
        mServiceState (serviceState),
        mId(SERVICESTATUS_DATA_ITEM_ID) {}
    virtual ~ServiceStatusDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    int32_t mServiceState;
protected:
    DataItemId mId;
};

class ModelDataItemBase : public IDataItemCore {
public:
    ModelDataItemBase(const string & name) :
        mModel (name),
        mId(MODEL_DATA_ITEM_ID) {}
    virtual ~ModelDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    string mModel;
protected:
    DataItemId mId;
};

class ManufacturerDataItemBase : public IDataItemCore {
public:
    ManufacturerDataItemBase(const string & name) :
        mManufacturer (name),
        mId(MANUFACTURER_DATA_ITEM_ID) {}
    virtual ~ManufacturerDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    string mManufacturer;
protected:
    DataItemId mId;
};

class RilServiceInfoDataItemBase : public IDataItemCore {
public:
    inline RilServiceInfoDataItemBase() :
            mData(nullptr), mId(RILSERVICEINFO_DATA_ITEM_ID) {}
    inline virtual ~RilServiceInfoDataItemBase() { if (nullptr != mData) free(mData); }
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
    inline RilServiceInfoDataItemBase(const RilServiceInfoDataItemBase& peer) :
            RilServiceInfoDataItemBase() {
        peer.setPeerData(*this);
    }
    inline virtual bool operator==(const RilServiceInfoDataItemBase& other) const {
        return other.mData == mData;
    }
    inline virtual void setPeerData(RilServiceInfoDataItemBase& /*peer*/) const {}
    void* mData;
protected:
    DataItemId mId;
};

class RilCellInfoDataItemBase : public IDataItemCore {
public:
    inline RilCellInfoDataItemBase() :
            mData(nullptr), mId(RILCELLINFO_DATA_ITEM_ID) {}
    inline virtual ~RilCellInfoDataItemBase() { if (nullptr != mData) free(mData); }
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
    inline RilCellInfoDataItemBase(const RilCellInfoDataItemBase& peer) :
            RilCellInfoDataItemBase() {
        peer.setPeerData(*this);
    }
    inline virtual bool operator==(const RilCellInfoDataItemBase& other) const {
        return other.mData == mData;
    }
    inline virtual void setPeerData(RilCellInfoDataItemBase& /*peer*/) const {}
    void* mData;
protected:
    DataItemId mId;
};

class WifiSupplicantStatusDataItemBase : public IDataItemCore {
public:
    WifiSupplicantStatusDataItemBase() :
        mState((WifiSupplicantState)WIFI_SUPPLICANT_DEFAULT_STATE),
        mApMacAddressValid(false),
        mWifiApSsidValid(false),
        mId(WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID) {
            memset (&mApMacAddress, 0, sizeof (mApMacAddress));
            mWifiApSsid.clear();
        }
    virtual ~WifiSupplicantStatusDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
    // Data members
    typedef enum WifiSupplicantState {
        DISCONNECTED,
        INTERFACE_DISABLED,
        INACTIVE,
        SCANNING,
        AUTHENTICATING,
        ASSOCIATING,
        ASSOCIATED,
        FOUR_WAY_HANDSHAKE,
        GROUP_HANDSHAKE,
        COMPLETED,
        DORMANT,
        UNINITIALIZED,
        INVALID
    } WifiSupplicantState;
    /* Represents whether access point attach state*/
    WifiSupplicantState mState;
    /* Represents info on whether ap mac address is valid */
    bool mApMacAddressValid;
    /* Represents mac address of the wifi access point*/
    uint8_t mApMacAddress[MAC_ADDRESS_LENGTH];
    /* Represents info on whether ap SSID is valid */
    bool mWifiApSsidValid;
    /* Represents Wifi SSID string*/
    string mWifiApSsid;
protected:
    DataItemId mId;
};

class TacDataItemBase : public IDataItemCore {
public:
    TacDataItemBase(const string & name) :
        mValue (name),
        mId(TAC_DATA_ITEM_ID) {}
    virtual ~TacDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    string mValue;
protected:
    DataItemId mId;
};

class MccmncDataItemBase : public IDataItemCore {
public:
    MccmncDataItemBase(const string & name) :
        mValue(name),
        mId(MCCMNC_DATA_ITEM_ID) {}
    virtual ~MccmncDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
// Data members
    string mValue;
protected:
    DataItemId mId;
};

class SrnDeviceScanDetailsDataItemBase : public IDataItemCore {
public:
    SrnDeviceScanDetailsDataItemBase(DataItemId Id) :
        mValidSrnData(false),
        mApSrnRssi(-1),
        mApSrnTimestamp(0),
        mRequestTimestamp(0),
        mReceiveTimestamp(0),
        mErrorCause(-1),
        mId(Id) {}
    virtual ~SrnDeviceScanDetailsDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
    // Data members common to all SRN tech types
    /* Represents info on whether SRN data is valid (no error)*/
    bool mValidSrnData;
    /* SRN device RSSI reported */
    int32_t mApSrnRssi;
    /* MAC adress of SRN device */
    uint8_t mApSrnMacAddress[SRN_MAC_ADDRESS_LENGTH];
    /* UTC timestamp at which the scan was requested.for this SRN device*/
    int64_t mApSrnTimestamp;
    /* UTC timestamp at which the scan was started. */
    int64_t mRequestTimestamp;
    /* UTC timestamp at which the scan was received.*/
    int64_t mReceiveTimestamp;
    /* Reason for the error/failure if SRN details are not valid */
    int32_t mErrorCause;
protected:
    DataItemId mId;
};

class BtDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase {

public:
    BtDeviceScanDetailsDataItemBase() :
        SrnDeviceScanDetailsDataItemBase(BT_SCAN_DATA_ITEM_ID) {}
    virtual ~BtDeviceScanDetailsDataItemBase() {}
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
};

class BtLeDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase {

public:
    BtLeDeviceScanDetailsDataItemBase() :
        SrnDeviceScanDetailsDataItemBase(BTLE_SCAN_DATA_ITEM_ID) {}
    virtual ~BtLeDeviceScanDetailsDataItemBase() {}
    virtual void stringify(string& /*valueStr*/) {}
    virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
};

class BatteryLevelDataItemBase : public IDataItemCore {
public:
    inline BatteryLevelDataItemBase(uint8_t batteryPct) :
            mBatteryPct(batteryPct), mId(BATTERY_LEVEL_DATA_ITEM_ID) {}
    inline ~BatteryLevelDataItemBase() {}
    inline virtual DataItemId getId() { return mId; }
// Data members
    uint8_t mBatteryPct;
protected:
    DataItemId mId;
};

} // namespace loc_core

#endif //__DATAITEMCONCRETEBASETYPES__


code:
/* 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,

    // 26 -
    BATTERY_LEVEL_DATA_ITEM_ID,

    MAX_DATA_ITEM_ID_1_1,
} DataItemId;

#endif // #ifndef __DATAITEMID_H__


code:
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * 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 <loc_pla.h>
#include <log_util.h>
#include "loc_misc_utils.h"

namespace loc_core
{
void* DataItemsFactoryProxy::dataItemLibHandle = NULL;
get_concrete_data_item_fn* DataItemsFactoryProxy::getConcreteDIFunc = NULL;

IDataItemCore* DataItemsFactoryProxy::createNewDataItem(DataItemId id)
{
    IDataItemCore *mydi = nullptr;

    if (NULL != getConcreteDIFunc) {
        mydi = (*getConcreteDIFunc)(id);
    }
    else {
        getConcreteDIFunc = (get_concrete_data_item_fn * )
                dlGetSymFromLib(dataItemLibHandle, DATA_ITEMS_LIB_NAME, DATA_ITEMS_GET_CONCRETE_DI);

        if (NULL != getConcreteDIFunc) {
            LOC_LOGd("Loaded function %s : %p", DATA_ITEMS_GET_CONCRETE_DI, getConcreteDIFunc);
            mydi = (*getConcreteDIFunc)(id);
        }
        else {
            // dlysm failed.
            const char * err = dlerror();
            if (NULL == err)
            {
                err = "Unknown";
            }
            LOC_LOGe("failed to find symbol %s; error=%s", DATA_ITEMS_GET_CONCRETE_DI, err);
        }
    }
    return mydi;
}

void DataItemsFactoryProxy::closeDataItemLibraryHandle()
{
    if (NULL != dataItemLibHandle) {
        dlclose(dataItemLibHandle);
        dataItemLibHandle = NULL;
    }
}

} // namespace loc_core


code:
/* 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__


code:
/* 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__


code:
/* Copyright (c) 2011-2015, 2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_core_log"

#include <log_util.h>
#include <loc_log.h>
#include <loc_core_log.h>
#include <loc_pla.h>

void LocPosMode::logv() const
{
    LOC_LOGV ("Position mode: %s\n  Position recurrence: %s\n  "
              "min interval: %d\n  preferred accuracy: %d\n  "
              "preferred time: %d\n  credentials: %s  provider: %s \n  "
              "power mode: %d\n  tbm %d",
              loc_get_position_mode_name(mode),
              loc_get_position_recurrence_name(recurrence),
              min_interval,
              preferred_accuracy,
              preferred_time,
              credentials,
              provider,
              powerMode,
              timeBetweenMeasurements);
}

/* GPS status names */
DECLARE_TBL(gps_status_name) =
{
    NAME_VAL( LOC_GPS_STATUS_NONE ),
    NAME_VAL( LOC_GPS_STATUS_SESSION_BEGIN ),
    NAME_VAL( LOC_GPS_STATUS_SESSION_END ),
    NAME_VAL( LOC_GPS_STATUS_ENGINE_ON ),
    NAME_VAL( LOC_GPS_STATUS_ENGINE_OFF ),
};

/* Find Android GPS status name */
const char* loc_get_gps_status_name(LocGpsStatusValue gps_status)
{
    return loc_get_name_from_val(gps_status_name_tbl, (int64_t) gps_status);
}

DECLARE_TBL(loc_eng_position_modes) =
{
    NAME_VAL( LOC_POSITION_MODE_STANDALONE ),
    NAME_VAL( LOC_POSITION_MODE_MS_BASED ),
    NAME_VAL( LOC_POSITION_MODE_MS_ASSISTED ),
    NAME_VAL( LOC_POSITION_MODE_RESERVED_1 ),
    NAME_VAL( LOC_POSITION_MODE_RESERVED_2 ),
    NAME_VAL( LOC_POSITION_MODE_RESERVED_3 ),
    NAME_VAL( LOC_POSITION_MODE_RESERVED_4 ),
    NAME_VAL( LOC_POSITION_MODE_RESERVED_5 )
};

const char* loc_get_position_mode_name(LocGpsPositionMode mode)
{
    return loc_get_name_from_val(loc_eng_position_modes_tbl, (int64_t) mode);
}

DECLARE_TBL(loc_eng_position_recurrences) =
{
    NAME_VAL( LOC_GPS_POSITION_RECURRENCE_PERIODIC ),
    NAME_VAL( LOC_GPS_POSITION_RECURRENCE_SINGLE )
};

const char* loc_get_position_recurrence_name(LocGpsPositionRecurrence recur)
{
    return loc_get_name_from_val(loc_eng_position_recurrences_tbl, (int64_t) recur);
}

const char* loc_get_aiding_data_mask_names(LocGpsAidingData /*data*/)
{
    return NULL;
}

DECLARE_TBL(loc_eng_agps_types) =
{
    NAME_VAL( LOC_AGPS_TYPE_INVALID ),
    NAME_VAL( LOC_AGPS_TYPE_ANY ),
    NAME_VAL( LOC_AGPS_TYPE_SUPL ),
    NAME_VAL( LOC_AGPS_TYPE_C2K ),
    NAME_VAL( LOC_AGPS_TYPE_WWAN_ANY )
};

const char* loc_get_agps_type_name(LocAGpsType type)
{
    return loc_get_name_from_val(loc_eng_agps_types_tbl, (int64_t) type);
}

DECLARE_TBL(loc_eng_ni_types) =
{
    NAME_VAL( LOC_GPS_NI_TYPE_VOICE ),
    NAME_VAL( LOC_GPS_NI_TYPE_UMTS_SUPL ),
    NAME_VAL( LOC_GPS_NI_TYPE_UMTS_CTRL_PLANE ),
    NAME_VAL( LOC_GPS_NI_TYPE_EMERGENCY_SUPL )
};

const char* loc_get_ni_type_name(LocGpsNiType type)
{
    return loc_get_name_from_val(loc_eng_ni_types_tbl, (int64_t) type);
}

DECLARE_TBL(loc_eng_ni_responses) =
{
    NAME_VAL( LOC_GPS_NI_RESPONSE_ACCEPT ),
    NAME_VAL( LOC_GPS_NI_RESPONSE_DENY ),
    NAME_VAL( LOC_GPS_NI_RESPONSE_DENY )
};

const char* loc_get_ni_response_name(LocGpsUserResponseType response)
{
    return loc_get_name_from_val(loc_eng_ni_responses_tbl, (int64_t) response);
}

DECLARE_TBL(loc_eng_ni_encodings) =
{
    NAME_VAL( LOC_GPS_ENC_NONE ),
    NAME_VAL( LOC_GPS_ENC_SUPL_GSM_DEFAULT ),
    NAME_VAL( LOC_GPS_ENC_SUPL_UTF8 ),
    NAME_VAL( LOC_GPS_ENC_SUPL_UCS2 ),
    NAME_VAL( LOC_GPS_ENC_UNKNOWN )
};

const char* loc_get_ni_encoding_name(LocGpsNiEncodingType encoding)
{
    return loc_get_name_from_val(loc_eng_ni_encodings_tbl, (int64_t) encoding);
}

DECLARE_TBL(loc_eng_agps_bears) =
{
    NAME_VAL( AGPS_APN_BEARER_INVALID ),
    NAME_VAL( AGPS_APN_BEARER_IPV4 ),
    NAME_VAL( AGPS_APN_BEARER_IPV6 ),
    NAME_VAL( AGPS_APN_BEARER_IPV4V6 )
};

const char* loc_get_agps_bear_name(AGpsBearerType bearer)
{
    return loc_get_name_from_val(loc_eng_agps_bears_tbl, (int64_t) bearer);
}

DECLARE_TBL(loc_eng_server_types) =
{
    NAME_VAL( LOC_AGPS_CDMA_PDE_SERVER ),
    NAME_VAL( LOC_AGPS_CUSTOM_PDE_SERVER ),
    NAME_VAL( LOC_AGPS_MPC_SERVER ),
    NAME_VAL( LOC_AGPS_SUPL_SERVER )
};

const char* loc_get_server_type_name(LocServerType type)
{
    return loc_get_name_from_val(loc_eng_server_types_tbl, (int64_t) type);
}

DECLARE_TBL(loc_eng_position_sess_status_types) =
{
    NAME_VAL( LOC_SESS_SUCCESS ),
    NAME_VAL( LOC_SESS_INTERMEDIATE ),
    NAME_VAL( LOC_SESS_FAILURE )
};

const char* loc_get_position_sess_status_name(enum loc_sess_status status)
{
    return loc_get_name_from_val(loc_eng_position_sess_status_types_tbl, (int64_t) status);
}

DECLARE_TBL(loc_eng_agps_status_names) =
{
    NAME_VAL( LOC_GPS_REQUEST_AGPS_DATA_CONN ),
    NAME_VAL( LOC_GPS_RELEASE_AGPS_DATA_CONN ),
    NAME_VAL( LOC_GPS_AGPS_DATA_CONNECTED ),
    NAME_VAL( LOC_GPS_AGPS_DATA_CONN_DONE ),
    NAME_VAL( LOC_GPS_AGPS_DATA_CONN_FAILED )
};

const char* loc_get_agps_status_name(LocAGpsStatusValue status)
{
    return loc_get_name_from_val(loc_eng_agps_status_names_tbl, (int64_t) status);
}


code:
/* Copyright (c) 2011-2013, 2016-2017 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef LOC_CORE_LOG_H
#define LOC_CORE_LOG_H

#include <ctype.h>
#include <gps_extended.h>

#ifdef __cplusplus
extern "C"
{
#endif

const char* loc_get_gps_status_name(LocGpsStatusValue gps_status);
const char* loc_get_position_mode_name(LocGpsPositionMode mode);
const char* loc_get_position_recurrence_name(LocGpsPositionRecurrence recur);
const char* loc_get_aiding_data_mask_names(LocGpsAidingData data);
const char* loc_get_agps_type_name(LocAGpsType type);
const char* loc_get_ni_type_name(LocGpsNiType type);
const char* loc_get_ni_response_name(LocGpsUserResponseType response);
const char* loc_get_ni_encoding_name(LocGpsNiEncodingType encoding);
const char* loc_get_agps_bear_name(AGpsBearerType bear);
const char* loc_get_server_type_name(LocServerType type);
const char* loc_get_position_sess_status_name(enum loc_sess_status status);
const char* loc_get_agps_status_name(LocAGpsStatusValue status);

#ifdef __cplusplus
}
#endif

#endif /* LOC_CORE_LOG_H */


code:
/* 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__


code:
/* 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__


code:
/* Copyright (c) 2017, 2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * 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 <string>
#include  <DataItemId.h>

using namespace std;

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;

#ifdef USE_GLIB
    /**
     * @brief Setup WWAN backhaul
     * @details  Setup WWAN backhaul
     *
     * @param None
     */
    virtual bool connectBackhaul(const string& clientName) = 0;

    /**
     * @brief Disconnects the WWANbackhaul
     * @details Disconnects the WWANbackhaul, only if it was setup by us
     *
     * @param None
     */
    virtual bool disconnectBackhaul(const string& clientName) = 0;
#endif

    /**
     * @brief Destructor
     * @details Destructor
     */
    virtual ~IFrameworkActionReq () {}
};

} // namespace loc_core

#endif // #ifndef __IFRAMEWORKACTIONREQ_H__


code:
/* Copyright (c) 2017, 2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * 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*/) {}
#ifdef USE_GLIB
    inline virtual bool connectBackhaul(const string& clientName) { return false; }
    inline virtual bool disconnectBackhaul(const string& clientName) { return false; }
#endif

    /**
     * @brief Destructor
     * @details Destructor
     */
    virtual ~IOsObserver () {}
};

} // namespace loc_core

#endif // #ifndef __IOSOBSERVER_H__


code:
prebuilt_etc {

    name: "apdr.conf",
    vendor: true,
    src: "apdr.conf",
}

prebuilt_etc {

    name: "gps.conf",
    vendor: true,
    src: "gps.conf",
}

prebuilt_etc {

    name: "flp.conf",
    vendor: true,
    src: "flp.conf",
}

prebuilt_etc {

    name: "gnss_antenna_info.conf",
    vendor: true,
    src: "gnss_antenna_info.conf",
}

prebuilt_etc {

    name: "izat.conf",
    vendor: true,
    src: "izat.conf",
}

prebuilt_etc {

    name: "lowi.conf",
    vendor: true,
    src: "lowi.conf",
}

prebuilt_etc {

    name: "sap.conf",
    vendor: true,
    src: "sap.conf",
}

prebuilt_etc {

    name: "xtwifi.conf",
    vendor: true,
    src: "xtwifi.conf",
}

prebuilt_etc {
    name: "gnss@2.0-base.policy",
    vendor: true,
    sub_dir: "seccomp_policy",
    src: "seccomp_policy/gnss@2.0-base.policy",
}

prebuilt_etc {
    name: "gnss@2.0-xtra-daemon.policy",
    vendor: true,
    sub_dir: "seccomp_policy",
    src: "seccomp_policy/gnss@2.0-xtra-daemon.policy",
}

prebuilt_etc {
    name: "gnss@2.0-xtwifi-client.policy",
    vendor: true,
    sub_dir: "seccomp_policy",
    src: "seccomp_policy/gnss@2.0-xtwifi-client.policy",
}

prebuilt_etc {
    name: "gnss@2.0-xtwifi-inet-agent.policy",
    vendor: true,
    sub_dir: "seccomp_policy",
    src: "seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy",
}


code:
# AP DR SENSOR Configuration file
#
# SENSOR_SERVICE options are one of below
#   accel,gyro,vehicle_accel,vehicle_gyro,pedometer,vehicle_odometry,accel_temp,
#   gyro_temp,baro,mag_calib,mag_uncalib,amd,rmd.
#
# SENSOR_PROVIDER options is one of -- default,native,ssc,samlite.
#
# SENSOR_RATE = 1~100 (Hz)
#
# SENSOR_SAMPLES = 1~N
#
# SENSOR_STATISTIC_ENABLED
#  bit 0: Diag Print Enabled
#  bit 1: Adb  Print Enabled
# SENSOR_STATISTIC_PRINT_COUNT
#  Skip Number of Print
#
# QDR_DYNAMIC_LOADING = 1~3
# Configure QDR library to be loaded
#   1: QDR3
#   2: QDR2-GYRO
#   3: QDR2-DWT
#
#

######################################
#                                    #
#   QDR3 Configuration               #
#                                    #
# For QDR3,                          #
# comment default configuration above#
# and                                #
# uncomment below configuration      #
# settings.                          #
#                                    #
######################################
#
SENSOR_SERVICE = accel
SENSOR_PROVIDER = native
SENSOR_RATE = 10
SENSOR_SAMPLES = 10
#
SENSOR_SERVICE = vehicle_speed
SENSOR_PROVIDER = native
SENSOR_RATE = 100
SENSOR_SAMPLES = 1
#
SENSOR_SERVICE = gyro
SENSOR_PROVIDER = native
SENSOR_RATE = 10
SENSOR_SAMPLES = 10
#
SENSOR_SERVICE = vehicle_gear
SENSOR_PROVIDER = native
SENSOR_RATE = 100
SENSOR_SAMPLES = 1
#
SENSOR_SERVICE = accel_temp
SENSOR_PROVIDER = native
SENSOR_RATE = 1
SENSOR_SAMPLES = 1
#
#
##Configure QDR library to be loaded 1: QDR3 2: QDR2-GYRO 3: QDR2-DWS
QDR_DYNAMIC_LOADING = 1
##Specify CAN sensor type: Valid Options: 14(ODO), 2(ODO_DWT), 3(ODO_DWS)
QDR_CAN_TYPE = 14
##Reporting offset before PPS boundary
QDR_REPORTING_OFFSET = 20
#

##Vehicle Sensor Configuration (CAN data availability)
##QDR_VEH_SENSOR_CONFIG:
##   0: VEHICLE_SENSOR_PRESENT  - Vehicle Sensor is available (DEFAULT)
##   1: VEHICLE_SENSOR_OPTIONAL - Vehicle Sensor may or may not be present.
#QDR_VEH_SENSOR_CONFIG = 0

##Select Wheel set (E.g.: Front two wheels, Rear two wheels OR All four wheels)
##To be used for differential wheel tick OR speed service.
##This configuration is applicable when QDR_CAN_TYPE configured as
##ODO_DWS(3) or ODO_DWT(2).
##Value "0": Use Front two wheels
##Value "1": Use Rear two wheels
##Value "2": Use All four wheels
#QG_DRIVE_WHEEL_FW_RW_AW = 2
##Max Wheel tick value above which wheel tick rolls over
##This configuration is applicable when QDR_CAN_TYPE configured as ODO_DWT(2)
#QG_DWT_MAX_WHEEL_TICK_COUNT = 255.0
##Configure Wheel constant for DWT based below equation
##(2 * pi * WHEEL_RADIUS / Pulses Per revolution)
##This configuration is applicable when QDR_CAN_TYPE configured as ODO_DWT(2)
#QG_DWT_WHEEL_CONSTANT = 0.044
#

######################################
#                                    #
#   QDR2-DWT Configuration           #
#                                    #
# For QDR2-DWT,                      #
# comment default configuration above#
# and                                #
# uncomment below configuration      #
# settings.                          #
#                                    #
######################################
#
#SENSOR_SERVICE = vehicle_speed
#SENSOR_PROVIDER = native
#SENSOR_RATE = 100
#SENSOR_SAMPLES = 1
#SENSOR_STATISTIC_ENABLED = 3
#SENSOR_STATISTIC_PRINT_COUNT = 50
#
#SENSOR_SERVICE = vehicle_dws
#SENSOR_PROVIDER = native
#SENSOR_RATE = 100
#SENSOR_SAMPLES = 1
#SENSOR_STATISTIC_ENABLED = 3
#SENSOR_STATISTIC_PRINT_COUNT = 50
#
#SENSOR_SERVICE = vehicle_gear
#SENSOR_PROVIDER = native
#SENSOR_RATE = 100
#SENSOR_SAMPLES = 1
#SENSOR_STATISTIC_ENABLED = 3
#SENSOR_STATISTIC_PRINT_COUNT = 50
#
#GNSS_POS_STATISTIC_ENABLED = 3
#GNSS_POS_STATISTIC_PRNTCNT = 10
#GNSS_MSR_STATISTIC_ENABLED = 3
#GNSS_MSR_STATISTIC_PRNTCNT = 10
#
##Configure QDR library to be loaded 1: QDR3 2: QDR2-GYRO 3: QDR2-DWS
#QDR_DYNAMIC_LOADING = 3
##Enable/disable sensor data flashback feature
#QDR_FLASHBACK_ENABLED = 0
##Enable/disable sensor data batching feature
#QDR_BATCHING_ENABLED = 0
##Reporting offset before PPS boundary
#QDR_REPORTING_OFFSET = 20
##Sensor dispatch threshold declaration
#QDR_SENSDISPATCH_MS = 30

######################################
#                                    #
#   QDR2-GYRO Configuration          #
#                                    #
# For QDR2-GYRO,                     #
# comment default configuration above#
# and                                #
# uncomment below configuration      #
# settings.                          #
#                                    #
######################################
#
#SENSOR_SERVICE = vehicle_speed
#SENSOR_PROVIDER = native
#SENSOR_RATE = 100
#SENSOR_SAMPLES = 1
#
#SENSOR_SERVICE = vehicle_gyro
#SENSOR_PROVIDER = native
#SENSOR_RATE = 100
#SENSOR_SAMPLES = 1
#
#SENSOR_SERVICE = vehicle_gear
#SENSOR_PROVIDER = native
#SENSOR_RATE = 100
#SENSOR_SAMPLES = 1
#
##Configure QDR library to be loaded 1: QDR3 2: QDR2-GYRO 3: QDR2-DWS
#QDR_DYNAMIC_LOADING = 2
##Enable/disable sensor data flashback feature
#QDR_FLASHBACK_ENABLED = 0
##Enable/disable sensor data batching feature
#QDR_BATCHING_ENABLED = 0
##Reporting offset before PPS boundary
#QDR_REPORTING_OFFSET = 20
##Sensor dispatch threshold declaration
#QDR_SENSDISPATCH_MS = 30
#


code:
###################################
#####       FLP settings      #####
###################################

###################################
# FLP BATCH SIZE
###################################
# The number of batched locations
# requested to modem. The desired number
# defined below may not be satisfied, as
# the modem can only return the number
# of batched locations that can be allocated,
# which is limited by memory. The default
# batch size defined as 20 as below.
BATCH_SIZE=40

###################################
# FLP OUTDOOR TRIP BATCH SIZE
###################################
# The number of batched locations
# requested to modem for outdoor
# trip batching. The desired number
# defined below may not be satisfied, as
# the modem can only return the number
# of batched locations that can be allocated,
# which is limited by memory. The default
# trip batch size defined as 600 as below.
OUTDOOR_TRIP_BATCH_SIZE=600

###################################
# FLP BATCHING SESSION TIMEOUT
###################################
# Duration with which batch session timeout
# happens in milliseconds. If not specified
# or set to zero, batching session timeout
# defaults to 20 seconds by the modem.
# BATCH_SESSION_TIMEOUT=20000

###################################
# FLP BATCHING ACCURACY
###################################
# Set to one of the defined values below
# to define the accuracy of batching.
# If not specified, accuracy defaults
# to LOW.
# FLP BATCHING ACCURACY values:
# Low accuracy = 0
# Medium accuracy = 1
# High accuracy = 2
ACCURACY=1

####################################
# By default if network fixes are not sensor assisted
# these fixes must be dropped. This parameter adds an exception
# for targets where there is no PDR and we still want to
# report out network fixes
# 0: MUST NOT ALLOW NETWORK FIXES
# 1: ALLOW NETWORK FIXES
####################################
ALLOW_NETWORK_FIXES = 0