diff options
author | Harikrishnan Hariharan <hahariha@codeaurora.org> | 2017-08-11 17:36:10 +0530 |
---|---|---|
committer | Katz Yamada <kyamada@codeaurora.org> | 2017-09-07 11:05:15 -0700 |
commit | ff8b31761cff3098444c41c8daa7baa6dff92ccd (patch) | |
tree | 8588ec5f2b0b602e09d731cc6ce51bb31c539fb6 /core/SystemStatusOsObserver.cpp | |
parent | 6ef3b747143c590d40e50299529f40cde8c15e2a (diff) | |
download | gps-ff8b31761cff3098444c41c8daa7baa6dff92ccd.tar.gz |
Integrate XtraSysStatObs with SystemStatusObserver
Use SystemStatusObserver to subscribe for dataitems in
XtraSystemStatusObserver.
Change-Id: Ib1828b9025c9c5bb5194a36014249472ed3f6f9e
CRs-Fixed: 2093290
Diffstat (limited to 'core/SystemStatusOsObserver.cpp')
-rw-r--r-- | core/SystemStatusOsObserver.cpp | 991 |
1 files changed, 469 insertions, 522 deletions
diff --git a/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp index e327f93..319f1d7 100644 --- a/core/SystemStatusOsObserver.cpp +++ b/core/SystemStatusOsObserver.cpp @@ -28,618 +28,565 @@ */ #define LOG_TAG "LocSvc_SystemStatusOsObserver" -#include <string> -#include <cinttypes> -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> -#include <pthread.h> -#include <iterator> #include <algorithm> - -#include <MsgTask.h> +#include <SystemStatus.h> #include <SystemStatusOsObserver.h> - -#include <DataItemId.h> #include <IDataItemCore.h> #include <IClientIndex.h> #include <IDataItemIndex.h> #include <IndexFactory.h> - #include <DataItemsFactoryProxy.h> -#include <platform_lib_log_util.h> - namespace loc_core { -#define BREAK_IF_ZERO(ERR,X) if(0==(X)) {result = (ERR); break;} -#define BREAK_IF_NON_ZERO(ERR,X) if(0!=(X)) {result = (ERR); break;} - SystemStatusOsObserver::SystemStatusOsObserver(const MsgTask* msgTask) : - mAddress ("SystemStatusOsObserver"), - mClientIndex(IndexFactory <IDataItemObserver *, DataItemId> :: createClientIndex ()), - mDataItemIndex(IndexFactory <IDataItemObserver *, DataItemId> :: createDataItemIndex ()) + mAddress("SystemStatusOsObserver"), + mClientIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createClientIndex()), + mDataItemIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createDataItemIndex()) { - int result = -1; - ENTRY_LOG (); - do { - BREAK_IF_ZERO (1, mClientIndex); - BREAK_IF_ZERO (2, mDataItemIndex); - mContext.mMsgTask = msgTask; - result = 0; - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + mContext.mMsgTask = msgTask; } -SystemStatusOsObserver :: ~SystemStatusOsObserver () +SystemStatusOsObserver::~SystemStatusOsObserver() { // Close data-item library handle DataItemsFactoryProxy::closeDataItemLibraryHandle(); // Destroy cache - map <DataItemId, IDataItemCore *> :: iterator citer = mDataItemCache.begin (); - for (; citer != mDataItemCache.end (); ++citer) { - if (citer->second != NULL) { delete citer->second; } + for (auto each : mDataItemCache) { + if (nullptr != each.second) { + delete each.second; + } } - mDataItemCache.clear (); + + mDataItemCache.clear(); delete mClientIndex; delete mDataItemIndex; - mClientIndex = NULL; - mDataItemIndex = NULL; } -/****************************************************************************** - Message proc -******************************************************************************/ -void SystemStatusOsObserver :: HandleSubscribeReq :: proc () const { - - int result = 0; - ENTRY_LOG (); - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - // Handle First Response - list <DataItemId> pendingFirstResponseList; - this->mParent->mClientIndex->add (this->mClient, mDataItemList, pendingFirstResponseList); - - // Do not send first response for only pendingFirstResponseList, - // instead send for all the data items (present in the cache) that - // have been subscribed for each time. - this->mParent->sendFirstResponse (mDataItemList, this->mClient); - - list <DataItemId> yetToSubscribeDataItemsList; - this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - // Send subscription list to framework - if (!yetToSubscribeDataItemsList.empty ()) { - this->mParent->mContext.mSubscriptionObj->subscribe - ( - yetToSubscribeDataItemsList, - this->mParent - ); - LOC_LOGD ("Subscribe Request sent to framework for the following data items"); - this->mParent->logMe (yetToSubscribeDataItemsList); - } +void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj) +{ + mContext.mSubscriptionObj = subscriptionObj; + + LOC_LOGD("Request cache size - Subscribe:%zu RequestData:%zu", + mSubscribeReqCache.size(), mReqDataCache.size()); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); - return; + // we have received the subscription object. process cached requests + // process - subscribe request cache + for (auto each : mSubscribeReqCache) { + subscribe(each.second, each.first); + } + // process - requestData request cache + for (auto each : mReqDataCache) { + requestData(each.second, each.first); + } } -void SystemStatusOsObserver :: HandleUpdateSubscriptionReq :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - list <DataItemId> currentlySubscribedList; - this->mParent->mClientIndex->getSubscribedList (this->mClient, currentlySubscribedList); - list <DataItemId> removeDataItemList; - set_difference (currentlySubscribedList.begin (), currentlySubscribedList.end (), - mDataItemList.begin (), mDataItemList.end (), - inserter (removeDataItemList,removeDataItemList.begin ())); - // Handle First Response - list <DataItemId> pendingFirstResponseList; - this->mParent->mClientIndex->add (this->mClient, mDataItemList, pendingFirstResponseList); - // Send First Response - this->mParent->sendFirstResponse (pendingFirstResponseList, this->mClient); - - list <DataItemId> yetToSubscribeDataItemsList; - this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - // Send subscription list to framework - if (!yetToSubscribeDataItemsList.empty ()) { - this->mParent->mContext.mSubscriptionObj->subscribe - ( - yetToSubscribeDataItemsList, - this->mParent - ); - LOC_LOGD ("Subscribe Request sent to framework for the following data items"); - this->mParent->logMe (yetToSubscribeDataItemsList); +// Helper to cache requests subscribe and requestData till subscription obj is obtained +void SystemStatusOsObserver::cacheObserverRequest(ObserverReqCache& reqCache, + const list<DataItemId>& l, IDataItemObserver* client) +{ + ObserverReqCache::iterator dicIter = reqCache.find(client); + if (dicIter != reqCache.end()) { + // found + list<DataItemId> difference(0); + set_difference(l.begin(), l.end(), + dicIter->second.begin(), dicIter->second.end(), + inserter(difference, difference.begin())); + if (!difference.empty()) { + difference.sort(); + dicIter->second.merge(difference); + dicIter->second.unique(); } + } + else { + // not found + reqCache[client] = l; + } +} - list <DataItemId> unsubscribeList; - list <DataItemId> unused; - this->mParent->mClientIndex->remove (this->mClient, removeDataItemList, unused); +/****************************************************************************** + IDataItemSubscription Overrides +******************************************************************************/ +void SystemStatusOsObserver::subscribe( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__); + cacheObserverRequest(mSubscribeReqCache, l, client); + return; + } - if (!this->mParent->mClientIndex->isSubscribedClient (this->mClient)) { - this->mParent->mDataItemIndex->remove (list <IDataItemObserver *> (1,this->mClient), unsubscribeList); - } - if (!unsubscribeList.empty ()) { - // Send unsubscribe to framework - this->mParent->mContext.mSubscriptionObj->unsubscribe - ( - unsubscribeList, - this->mParent - ); - LOC_LOGD ("Unsubscribe Request sent to framework for the following data items"); - this->mParent->logMe (unsubscribeList); - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + struct HandleSubscribeReq : public LocMsg { + HandleSubscribeReq(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleSubscribeReq() {} + void proc() const { -void SystemStatusOsObserver :: HandleRequestData :: proc () const { - int result = 0; - ENTRY_LOG (); + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; + } - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - list <DataItemId> yetToSubscribeDataItemsList; - this->mParent->mClientIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - // Send subscription list to framework - if (!mDataItemList.empty ()) { - this->mParent->mContext.mSubscriptionObj->requestData - ( - mDataItemList, - this->mParent - ); - LOC_LOGD ("Subscribe Request sent to framework for the following data items"); - this->mParent->logMe (yetToSubscribeDataItemsList); - } + // Handle First Response + list<DataItemId> pendingFirstResponseList(0); + mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList); - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + // Do not send first response for only pendingFirstResponseList, + // instead send for all the data items (present in the cache) that + // have been subscribed for each time. + mParent->sendFirstResponse(mDataItemList, mClient); -void SystemStatusOsObserver :: HandleUnsubscribeReq :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - list <DataItemId> unsubscribeList; - list <DataItemId> unused; - this->mParent->mClientIndex->remove (this->mClient, mDataItemList, unused); - - list <DataItemId> :: const_iterator it = mDataItemList.begin (); - for (; it != mDataItemList.end (); ++it) { - list <IDataItemObserver *> clientListSubs; - list <IDataItemObserver *> clientListOut; - this->mParent->mDataItemIndex->remove ((*it), - list <IDataItemObserver *> (1,this->mClient), clientListOut); - // check if there are any other subscribed client for this data item id - this->mParent->mDataItemIndex->getListOfSubscribedClients ( (*it), clientListSubs); - if (clientListSubs.empty()) - { - LOC_LOGD ("Client list subscribed is empty for dataitem - %d",(*it)); - unsubscribeList.push_back((*it)); - } - } - if (!unsubscribeList.empty ()) { - // Send unsubscribe to framework - this->mParent->mContext.mSubscriptionObj->unsubscribe - ( - unsubscribeList, - this->mParent - ); - LOC_LOGD ("Unsubscribe Request sent to framework for the following data items"); - this->mParent->logMe (unsubscribeList); - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + list<DataItemId> yetToSubscribeDataItemsList(0); + mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList); -void SystemStatusOsObserver :: HandleUnsubscribeAllReq :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - list <IDataItemObserver *> clients (1, this->mClient); - list <DataItemId> unsubscribeList; - BREAK_IF_NON_ZERO (2, this->mParent->mClientIndex->remove (this->mClient)); - - - this->mParent->mDataItemIndex->remove (clients, unsubscribeList); - if (!unsubscribeList.empty ()) { - // Send unsubscribe to framework - this->mParent->mContext.mSubscriptionObj->unsubscribe - ( - unsubscribeList, - this->mParent - ); - LOC_LOGD ("Unsubscribe Request sent to framework for the following data items"); - this->mParent->logMe (unsubscribeList); + // Send subscription list to framework + if (!yetToSubscribeDataItemsList.empty()) { + mParent->mContext.mSubscriptionObj->subscribe(yetToSubscribeDataItemsList, mParent); + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(yetToSubscribeDataItemsList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client)); } -void SystemStatusOsObserver :: HandleNotify :: getListOfClients - (const list <DataItemId> & dlist, list <IDataItemObserver *> & clients ) const { - - list <DataItemId> :: const_iterator it = dlist.begin (); - for (; it != dlist.end (); ++it) { - list <IDataItemObserver *> clientList; - this->mParent->mDataItemIndex->getListOfSubscribedClients ( (*it), clientList); - list <IDataItemObserver *> :: iterator citer = clientList.begin (); - for (; citer != clientList.end (); ++citer) { - clients.push_back (*citer); - } - clientList.clear (); - } - // remove duplicates - clients.unique (); -} +void SystemStatusOsObserver::updateSubscription( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); + return; + } -void SystemStatusOsObserver :: HandleNotify :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - // Update Cache with received data items and prepare - // list of data items to be sent. - list <IDataItemCore *> :: const_iterator it = mDList.begin (); - list <DataItemId> dataItemIdsToBeSent; - for (; it != mDList.end (); ++it) { - bool dataItemUpdated = false; - this->mParent->updateCache (*it, dataItemUpdated); - if (dataItemUpdated) { - dataItemIdsToBeSent.push_back ( (*it)->getId ()); + struct HandleUpdateSubscriptionReq : public LocMsg { + HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleUpdateSubscriptionReq() {} + void proc() const { + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; } - } - list <IDataItemObserver *> clientList; - this->getListOfClients (dataItemIdsToBeSent, clientList); - list <IDataItemObserver *> :: iterator citer = clientList.begin (); - // Send data item to all subscribed clients - LOC_LOGD ("LocTech-Label :: SystemStatusOsObserver :: Data Items Out"); - for (; citer != clientList.end (); ++citer) { - do { - list <DataItemId> dataItemIdsSubscribedByThisClient; - list <DataItemId> dataItemIdsToBeSentForThisClient; - this->mParent->mClientIndex->getSubscribedList (*citer, dataItemIdsSubscribedByThisClient); - dataItemIdsSubscribedByThisClient.sort (); - dataItemIdsToBeSent.sort (); - set_intersection (dataItemIdsToBeSent.begin (), - dataItemIdsToBeSent.end (), - dataItemIdsSubscribedByThisClient.begin (), - dataItemIdsSubscribedByThisClient.end (), - inserter (dataItemIdsToBeSentForThisClient, - dataItemIdsToBeSentForThisClient.begin ())); - BREAK_IF_NON_ZERO (4,this->mParent->sendCachedDataItems (dataItemIdsToBeSentForThisClient, *citer)); - dataItemIdsSubscribedByThisClient.clear (); - dataItemIdsToBeSentForThisClient.clear (); - } while (0); - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); -} + list<DataItemId> currentlySubscribedList(0); + mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList); -void SystemStatusOsObserver :: HandleTurnOn :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - // Send action turn on to framework - this->mParent->mContext.mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); -} + list<DataItemId> removeDataItemList(0); + set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(), + mDataItemList.begin(), mDataItemList.end(), + inserter(removeDataItemList,removeDataItemList.begin())); -void SystemStatusOsObserver :: HandleTurnOff :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - // Send action turn off to framework - this->mParent->mContext.mFrameworkActionReqObj->turnOff(mDataItemId); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); -} + // Handle First Response + list<DataItemId> pendingFirstResponseList(0); + mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList); -/****************************************************************************** - IDataItemSubscription Overrides -******************************************************************************/ -void SystemStatusOsObserver :: subscribe (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - HandleSubscribeReq * msg = new (nothrow) HandleSubscribeReq (this, l, client); - mContext.mMsgTask->sendMsg (msg); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + // Send First Response + mParent->sendFirstResponse(pendingFirstResponseList, mClient); -void SystemStatusOsObserver :: updateSubscription (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleUpdateSubscriptionReq (this, l, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; + list<DataItemId> yetToSubscribeDataItemsList(0); + mParent->mDataItemIndex->add( + mClient, mDataItemList, yetToSubscribeDataItemsList); + + // Send subscription list to framework + if (!yetToSubscribeDataItemsList.empty()) { + mParent->mContext.mSubscriptionObj->subscribe( + yetToSubscribeDataItemsList, mParent); + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(yetToSubscribeDataItemsList); + } + + list<DataItemId> unsubscribeList(0); + list<DataItemId> unused(0); + mParent->mClientIndex->remove(mClient, removeDataItemList, unused); + + if (!mParent->mClientIndex->isSubscribedClient(mClient)) { + mParent->mDataItemIndex->remove( + list<IDataItemObserver*> (1,mClient), unsubscribeList); + } + if (!unsubscribeList.empty()) { + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); + LOC_LOGD("Unsubscribe Request sent to framework for the following"); + mParent->logMe(unsubscribeList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client)); } -void SystemStatusOsObserver :: requestData (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleRequestData (this, l, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; - } - } while (0); +void SystemStatusOsObserver::requestData( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__); + cacheObserverRequest(mReqDataCache, l, client); + return; + } - EXIT_LOG_WITH_ERROR ("%d",result); -} + struct HandleRequestData : public LocMsg { + HandleRequestData(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleRequestData() {} + void proc() const { + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; + } -void SystemStatusOsObserver :: unsubscribe (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleUnsubscribeReq (this, l, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; + list<DataItemId> yetToSubscribeDataItemsList(0); + mParent->mClientIndex->add( + mClient, mDataItemList, yetToSubscribeDataItemsList); + mParent->mDataItemIndex->add( + mClient, mDataItemList, yetToSubscribeDataItemsList); + + // Send subscription list to framework + if (!mDataItemList.empty()) { + mParent->mContext.mSubscriptionObj->requestData(mDataItemList, mParent); + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(yetToSubscribeDataItemsList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client)); } -void SystemStatusOsObserver :: unsubscribeAll (IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleUnsubscribeAllReq (this, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; +void SystemStatusOsObserver::unsubscribe( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); + return; + } + struct HandleUnsubscribeReq : public LocMsg { + HandleUnsubscribeReq(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleUnsubscribeReq() {} + void proc() const { + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; + } + + list<DataItemId> unsubscribeList(0); + list<DataItemId> unused(0); + mParent->mClientIndex->remove(mClient, mDataItemList, unused); + + for (auto each : mDataItemList) { + list<IDataItemObserver*> clientListSubs(0); + list<IDataItemObserver*> clientListOut(0); + mParent->mDataItemIndex->remove( + each, list<IDataItemObserver*> (1,mClient), clientListOut); + // check if there are any other subscribed client for this data item id + mParent->mDataItemIndex->getListOfSubscribedClients(each, clientListSubs); + if (clientListSubs.empty()) + { + LOC_LOGD("Client list subscribed is empty for dataitem - %d", each); + unsubscribeList.push_back(each); + } + } + + if (!unsubscribeList.empty()) { + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); + LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); + mParent->logMe(unsubscribeList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, l, client)); } -/****************************************************************************** - IDataItemObserver Overrides -******************************************************************************/ -void SystemStatusOsObserver::getName(string & name) { - name = mAddress; -} +void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); + return; + } + + struct HandleUnsubscribeAllReq : public LocMsg { + HandleUnsubscribeAllReq(SystemStatusOsObserver* parent, + IDataItemObserver* client) : + mParent(parent), mClient(client) {} + virtual ~HandleUnsubscribeAllReq() {} + void proc() const { + list<IDataItemObserver*> clients(1, mClient); + list<DataItemId> unsubscribeList(0); + if(0 == mParent->mClientIndex->remove(mClient)) { + return; + } + mParent->mDataItemIndex->remove(clients, unsubscribeList); -void SystemStatusOsObserver::notify(const std::list <IDataItemCore *> & dlist) { - int result = 0; - ENTRY_LOG (); - do { - list <IDataItemCore *> :: const_iterator it = dlist.begin (); - list <IDataItemCore *> dataItemList; - list <DataItemId> ids; - LOC_LOGD("LocTech-Label :: SystemStatusOsObserver :: Data Items In"); - for (; it != dlist.end (); ++it) { - if (*it != NULL) { - string dv; - (*it)->stringify(dv); - LOC_LOGD("LocTech-Value :: Data Item Value: %s", dv.c_str ()); - IDataItemCore * dataitem = DataItemsFactoryProxy::createNewDataItem((*it)->getId()); - BREAK_IF_ZERO (2, dataitem); - // Copy contents into the newly created data item - dataitem->copy(*it); - dataItemList.push_back(dataitem); - ids.push_back((*it)->getId()); + if (!unsubscribeList.empty()) { + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); + LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); + mParent->logMe(unsubscribeList); } } - mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify (this, dataItemList)); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client)); } /****************************************************************************** - IFrameworkActionReq Overrides + IDataItemObserver Overrides ******************************************************************************/ -void SystemStatusOsObserver :: turnOn (DataItemId dit, int timeOut) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mFrameworkActionReqObj != NULL) { - // Check if data item exists in mActiveRequestCount - map <DataItemId, int> :: iterator citer = mActiveRequestCount.find (dit); - if (citer == mActiveRequestCount.end ()) { - // Data item not found in map - // Add reference count as 1 and add dataitem to map - pair <DataItemId, int> cpair (dit, 1); - mActiveRequestCount.insert (cpair); - LOC_LOGD("Sending turnOn request"); - // Send action turn on to framework - mContext.mMsgTask->sendMsg (new (nothrow) HandleTurnOn (this, dit, timeOut)); - } else { - // Found in map, update reference count - citer->second++; - LOC_LOGD("HandleTurnOn - Data item:%d Num_refs:%d",dit,citer->second); - } +void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist) +{ + list<IDataItemCore*> dataItemList(0); + + for (auto each : dlist) { + string dv; + each->stringify(dv); + LOC_LOGD("notify: DataItem In Value:%s", dv.c_str()); + + IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId()); + if (nullptr == di) { + LOC_LOGE("Unable to create dataitem:%d", each->getId()); + return; } - else { - LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); - result = 1; + + // Copy contents into the newly created data item + di->copy(each); + dataItemList.push_back(di); + // Request systemstatus to record this dataitem in its cache + SystemStatus* systemstatus = SystemStatus::getInstance(mContext.mMsgTask); + if(nullptr != systemstatus) { + systemstatus->eventDataItemNotify(di); } - } while (0); + } - EXIT_LOG_WITH_ERROR ("%d", result); -} + struct HandleNotify : public LocMsg { + HandleNotify(SystemStatusOsObserver* parent, const list<IDataItemCore*>& l) : + mParent(parent), mDList(l) {} + virtual ~HandleNotify() { + for (auto each : mDList) { + delete each; + } + } + void proc() const { + // Update Cache with received data items and prepare + // list of data items to be sent. + list<DataItemId> dataItemIdsToBeSent(0); + for (auto item : mDList) { + bool dataItemUpdated = false; + mParent->updateCache(item, dataItemUpdated); + if (dataItemUpdated) { + dataItemIdsToBeSent.push_back(item->getId()); + } + } -void SystemStatusOsObserver :: turnOff (DataItemId dit) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mFrameworkActionReqObj != NULL) { - // Check if data item exists in mActiveRequestCount - map <DataItemId, int> :: iterator citer = mActiveRequestCount.find (dit); - if (citer != mActiveRequestCount.end ()) { - citer->second--; - LOC_LOGD("HandleTurnOff - Data item:%d Remaining Num_refs:%d",dit,citer->second); - - if(citer->second == 0) { - LOC_LOGD("Sending turnOff request"); - // if this was last reference, remove item from map and turn off module - mActiveRequestCount.erase(citer); - // Send action turn off to framework - mContext.mMsgTask->sendMsg (new (nothrow) HandleTurnOff (this, dit)); + // Send data item to all subscribed clients + list<IDataItemObserver*> clientList(0); + for (auto each : dataItemIdsToBeSent) { + list<IDataItemObserver*> clients(0); + mParent->mDataItemIndex->getListOfSubscribedClients(each, clients); + for (auto each_cient: clients) { + clientList.push_back(each_cient); } - } else { - // Not found in map - LOC_LOGD ("Data item id %d not found in FrameworkModuleMap",dit); + } + clientList.unique(); + + for (auto client : clientList) { + list<DataItemId> dataItemIdsSubscribedByThisClient(0); + list<DataItemId> dataItemIdsToBeSentForThisClient(0); + mParent->mClientIndex->getSubscribedList( + client, dataItemIdsSubscribedByThisClient); + dataItemIdsSubscribedByThisClient.sort(); + dataItemIdsToBeSent.sort(); + + set_intersection(dataItemIdsToBeSent.begin(), + dataItemIdsToBeSent.end(), + dataItemIdsSubscribedByThisClient.begin(), + dataItemIdsSubscribedByThisClient.end(), + inserter(dataItemIdsToBeSentForThisClient, + dataItemIdsToBeSentForThisClient.begin())); + + mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client); + dataItemIdsSubscribedByThisClient.clear(); + dataItemIdsToBeSentForThisClient.clear(); } } - else { - LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); - result = 1; - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); + SystemStatusOsObserver* mParent; + const list<IDataItemCore*> mDList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList)); } /****************************************************************************** - Helpers + IFrameworkActionReq Overrides ******************************************************************************/ -void SystemStatusOsObserver :: logMe (const list <DataItemId> & l) { - list <DataItemId> :: const_iterator it = l.begin (); - for (;it != l.end (); ++it) { - LOC_LOGD ("DataItem %d",*it); +void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut) +{ + if (nullptr == mContext.mFrameworkActionReqObj) { + LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); + return; } -} -int SystemStatusOsObserver :: sendFirstResponse (const list <DataItemId> & l, IDataItemObserver * to) { - int result = 0; - ENTRY_LOG (); - do { - if (l.empty ()) { - LOC_LOGV("list is empty. Nothing to do. Exiting"); - result = 0; - break; - } + // Check if data item exists in mActiveRequestCount + map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit); + if (citer == mActiveRequestCount.end()) { + // Data item not found in map + // Add reference count as 1 and add dataitem to map + pair<DataItemId, int> cpair(dit, 1); + mActiveRequestCount.insert(cpair); + LOC_LOGD("Sending turnOn request"); - string clientName; - to->getName (clientName); - LOC_LOGD ("First response sent for the following data items To Client: %s", clientName.c_str()); - - list <IDataItemCore *> dataItems; - list <DataItemId> :: const_iterator diditer = l.begin (); - for (; diditer != l.end (); ++diditer) { - map <DataItemId, IDataItemCore*> :: const_iterator citer = mDataItemCache.find (*diditer); - if (citer != mDataItemCache.end ()) { - string dv; - IDataItemCore * di = citer->second; - di->stringify (dv); - LOC_LOGD ("LocTech-Value :: Data Item: %s", dv.c_str ()); - dataItems.push_back (citer->second); + // 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); } - } - if (dataItems.empty ()) { - LOC_LOGV("No items to notify. Nothing to do. Exiting"); - result = 0; - break; - } + IFrameworkActionReq* mFrameworkActionReqObj; + DataItemId mDataItemId; + int mTimeOut; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleTurnOnMsg(this, dit, timeOut)); + } + else { + // Found in map, update reference count + citer->second++; + LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second); + } +} - // Notify Client - to->notify (dataItems); +void SystemStatusOsObserver::turnOff(DataItemId dit) +{ + if (nullptr == mContext.mFrameworkActionReqObj) { + LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); + return; + } - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); - return result; + // Check if data item exists in mActiveRequestCount + map<DataItemId, int>::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)); + } + } } -int SystemStatusOsObserver :: sendCachedDataItems (const list <DataItemId> & l, IDataItemObserver * to) { - int result = 0; - ENTRY_LOG (); - do { - list <IDataItemCore *> dataItems; - list <DataItemId> :: const_iterator it = l.begin (); - string clientName; - to->getName (clientName); - LOC_LOGD ("LocTech-Value :: To Client: %s", clientName.c_str ()); - for (; it != l.end (); ++it) { +/****************************************************************************** + Helpers +******************************************************************************/ +void SystemStatusOsObserver::sendFirstResponse( + const list<DataItemId>& l, IDataItemObserver* to) +{ + if (l.empty()) { + LOC_LOGV("list is empty. Nothing to do. Exiting"); + return; + } + + string clientName; + to->getName(clientName); + list<IDataItemCore*> dataItems(0); + + for (auto each : l) { + map<DataItemId, IDataItemCore*>::const_iterator citer = mDataItemCache.find(each); + if (citer != mDataItemCache.end()) { string dv; - IDataItemCore * di = this->mDataItemCache [ (*it) ]; - di->stringify (dv); - LOC_LOGI("LocTech-Value :: Data Item: %s >> %s", dv.c_str(), clientName.c_str()); - dataItems.push_back (di); + citer->second->stringify(dv); + LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); + dataItems.push_back(citer->second); } + } + if (dataItems.empty()) { + LOC_LOGV("No items to notify. Nothing to do. Exiting"); + return; + } + to->notify(dataItems); +} - to->notify (dataItems); - - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); - return result; +void SystemStatusOsObserver::sendCachedDataItems( + const list<DataItemId>& l, IDataItemObserver* to) +{ + string clientName; + to->getName(clientName); + list<IDataItemCore*> dataItems(0); + + for (auto each : l) { + string dv; + IDataItemCore* di = mDataItemCache[each]; + di->stringify(dv); + LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); + dataItems.push_back(di); + } + to->notify(dataItems); } -int SystemStatusOsObserver :: updateCache (IDataItemCore * d, bool &dataItemUpdated) { - int result = 0; - ENTRY_LOG (); - do { - BREAK_IF_ZERO (1, d); - // Check if data item exists in cache - map <DataItemId, IDataItemCore*> :: iterator citer = mDataItemCache.find (d->getId ()); - if (citer == mDataItemCache.end ()) { - // New data item; not found in cache - IDataItemCore * dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId()); - BREAK_IF_ZERO (2, dataitem); - // Copy the contents of the data item - dataitem->copy (d); - pair <DataItemId, IDataItemCore*> cpair (d->getId (), dataitem); - // Insert in mDataItemCache - mDataItemCache.insert (cpair); - dataItemUpdated = true; - } else { - // Found in cache; Update cache if necessary - BREAK_IF_NON_ZERO(3, citer->second->copy (d, &dataItemUpdated)); - } +void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated) +{ + if (nullptr == d) { + return; + } - if (dataItemUpdated) { - LOC_LOGV("DataItem:%d updated:%d", d->getId (), dataItemUpdated); + // Check if data item exists in cache + map<DataItemId, IDataItemCore*>::iterator citer = + mDataItemCache.find(d->getId()); + if (citer == mDataItemCache.end()) { + // New data item; not found in cache + IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId()); + if (nullptr == dataitem) { + return; + } + + // Copy the contents of the data item + dataitem->copy(d); + pair<DataItemId, IDataItemCore*> cpair(d->getId(), dataitem); + // Insert in mDataItemCache + mDataItemCache.insert(cpair); + dataItemUpdated = true; + } + else { + // Found in cache; Update cache if necessary + if(0 == citer->second->copy(d, &dataItemUpdated)) { + return; } - } while (0); + } - EXIT_LOG_WITH_ERROR ("%d", result); - return result; + if (dataItemUpdated) { + LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated); + } } } // namespace loc_core |