1 /* Copyright (c) 2015-2017, 2020 The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation, nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 #ifndef __SYSTEM_STATUS_OSOBSERVER__ 30 #define __SYSTEM_STATUS_OSOBSERVER__ 31 32 #include <cinttypes> 33 #include <string> 34 #include <list> 35 #include <map> 36 #include <new> 37 #include <vector> 38 39 #include <MsgTask.h> 40 #include <DataItemId.h> 41 #include <IOsObserver.h> 42 #include <loc_pla.h> 43 #include <log_util.h> 44 #include <LocUnorderedSetMap.h> 45 46 namespace loc_core 47 { 48 /****************************************************************************** 49 SystemStatusOsObserver 50 ******************************************************************************/ 51 using namespace std; 52 using namespace loc_util; 53 54 // Forward Declarations 55 class IDataItemCore; 56 class SystemStatus; 57 class SystemStatusOsObserver; 58 typedef map<IDataItemObserver*, list<DataItemId>> ObserverReqCache; 59 typedef LocUnorderedSetMap<IDataItemObserver*, DataItemId> ClientToDataItems; 60 typedef LocUnorderedSetMap<DataItemId, IDataItemObserver*> DataItemToClients; 61 typedef unordered_map<DataItemId, IDataItemCore*> DataItemIdToCore; 62 typedef unordered_map<DataItemId, int> DataItemIdToInt; 63 #ifdef USE_GLIB 64 // Cache details of backhaul client requests 65 typedef unordered_set<string> ClientBackhaulReqCache; 66 #endif 67 68 struct ObserverContext { 69 IDataItemSubscription* mSubscriptionObj; 70 IFrameworkActionReq* mFrameworkActionReqObj; 71 const MsgTask* mMsgTask; 72 SystemStatusOsObserver* mSSObserver; 73 ObserverContextObserverContext74 inline ObserverContext(const MsgTask* msgTask, SystemStatusOsObserver* observer) : 75 mSubscriptionObj(NULL), mFrameworkActionReqObj(NULL), 76 mMsgTask(msgTask), mSSObserver(observer) {} 77 }; 78 79 // Clients wanting to get data from OS/Framework would need to 80 // subscribe with OSObserver using IDataItemSubscription interface. 81 // Such clients would need to implement IDataItemObserver interface 82 // to receive data when it becomes available. 83 class SystemStatusOsObserver : public IOsObserver { 84 85 public: 86 // ctor SystemStatusOsObserver(SystemStatus * systemstatus,const MsgTask * msgTask)87 inline SystemStatusOsObserver(SystemStatus* systemstatus, const MsgTask* msgTask) : 88 mSystemStatus(systemstatus), mContext(msgTask, this), 89 mAddress("SystemStatusOsObserver"), 90 mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID) {} 91 92 // dtor 93 ~SystemStatusOsObserver(); 94 95 template <typename CINT, typename COUT> 96 static COUT containerTransfer(CINT& s); 97 template <typename CINT, typename COUT> containerTransfer(CINT && s)98 inline static COUT containerTransfer(CINT&& s) { 99 return containerTransfer<CINT, COUT>(s); 100 } 101 102 // To set the subscription object 103 virtual void setSubscriptionObj(IDataItemSubscription* subscriptionObj); 104 105 // To set the framework action request object setFrameworkActionReqObj(IFrameworkActionReq * frameworkActionReqObj)106 inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) { 107 mContext.mFrameworkActionReqObj = frameworkActionReqObj; 108 #ifdef USE_GLIB 109 uint32_t numBackHaulClients = mBackHaulConnReqCache.size(); 110 if (numBackHaulClients > 0) { 111 // For each client, invoke connectbackhaul. 112 for (auto clientName : mBackHaulConnReqCache) { 113 LOC_LOGd("Invoke connectBackhaul for client: %s", clientName.c_str()); 114 connectBackhaul(clientName); 115 } 116 // Clear the set 117 mBackHaulConnReqCache.clear(); 118 } 119 #endif 120 } 121 122 // IDataItemSubscription Overrides subscribe(const list<DataItemId> & l,IDataItemObserver * client)123 inline virtual void subscribe(const list<DataItemId>& l, IDataItemObserver* client) override { 124 subscribe(l, client, false); 125 } 126 virtual void updateSubscription(const list<DataItemId>& l, IDataItemObserver* client) override; requestData(const list<DataItemId> & l,IDataItemObserver * client)127 inline virtual void requestData(const list<DataItemId>& l, IDataItemObserver* client) override { 128 subscribe(l, client, true); 129 } 130 virtual void unsubscribe(const list<DataItemId>& l, IDataItemObserver* client) override; 131 virtual void unsubscribeAll(IDataItemObserver* client) override; 132 133 // IDataItemObserver Overrides 134 virtual void notify(const list<IDataItemCore*>& dlist) override; getName(string & name)135 inline virtual void getName(string& name) override { 136 name = mAddress; 137 } 138 139 // IFrameworkActionReq Overrides 140 virtual void turnOn(DataItemId dit, int timeOut = 0) override; 141 virtual void turnOff(DataItemId dit) override; 142 #ifdef USE_GLIB 143 virtual bool connectBackhaul(const string& clientName) override; 144 virtual bool disconnectBackhaul(const string& clientName) override; 145 #endif 146 147 private: 148 SystemStatus* mSystemStatus; 149 ObserverContext mContext; 150 const string mAddress; 151 ClientToDataItems mClientToDataItems; 152 DataItemToClients mDataItemToClients; 153 DataItemIdToCore mDataItemCache; 154 DataItemIdToInt mActiveRequestCount; 155 156 // Cache the subscribe and requestData till subscription obj is obtained 157 void cacheObserverRequest(ObserverReqCache& reqCache, 158 const list<DataItemId>& l, IDataItemObserver* client); 159 #ifdef USE_GLIB 160 // Cache the framework action request for connect/disconnect 161 ClientBackhaulReqCache mBackHaulConnReqCache; 162 #endif 163 164 void subscribe(const list<DataItemId>& l, IDataItemObserver* client, bool toRequestData); 165 166 // Helpers 167 void sendCachedDataItems(const unordered_set<DataItemId>& s, IDataItemObserver* to); 168 bool updateCache(IDataItemCore* d); logMe(const unordered_set<DataItemId> & l)169 inline void logMe(const unordered_set<DataItemId>& l) { 170 IF_LOC_LOGD { 171 for (auto id : l) { 172 LOC_LOGD("DataItem %d", id); 173 } 174 } 175 } 176 }; 177 178 } // namespace loc_core 179 180 #endif //__SYSTEM_STATUS__ 181 182