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