• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "devicestatus_msdp_client_impl.h"
17 
18 #include <dlfcn.h>
19 #include <string>
20 #include <cerrno>
21 #include <sys/epoll.h>
22 #include <sys/timerfd.h>
23 #include <unistd.h>
24 #include <errors.h>
25 #include <linux/netlink.h>
26 
27 #include "devicestatus_common.h"
28 
29 using namespace OHOS::NativeRdb;
30 namespace OHOS {
31 namespace Msdp {
32 namespace {
33 constexpr int32_t ERR_OK = 0;
34 constexpr int32_t ERR_NG = -1;
35 const std::string DEVICESTATUS_SENSOR_HDI_LIB_PATH = "libdevicestatus_sensorhdi.z.so";
36 const std::string DEVICESTATUS_MSDP_ALGORITHM_LIB_PATH = "libdevicestatus_msdp.z.so";
37 const std::string ALGO_LIB_PATH = "libdevicestatus_algo.z.so";
38 std::map<DevicestatusDataUtils::DevicestatusType, DevicestatusDataUtils::DevicestatusValue> g_devicestatusDataMap;
39 DevicestatusMsdpClientImpl::CallbackManager g_callbacksMgr;
40 using clientType = DevicestatusDataUtils::DevicestatusType;
41 using clientValue = DevicestatusDataUtils::DevicestatusValue;
42 DevicestatusMsdpInterface* g_msdpInterface;
43 DevicestatusMsdpInterface* g_algo = nullptr;
44 }
45 
InitMsdpImpl(DevicestatusDataUtils::DevicestatusType type)46 ErrCode DevicestatusMsdpClientImpl::InitMsdpImpl(DevicestatusDataUtils::DevicestatusType type)
47 {
48     DEV_HILOGI(SERVICE, "Enter");
49     std::lock_guard<std::mutex> lock(mutex_);
50     if (g_algo == nullptr) {
51         g_algo = GetAlgoObj();
52         if (g_algo == nullptr) {
53             DEV_HILOGE(SERVICE, "get msdp module instance failed");
54             return ERR_NG;
55         }
56     }
57     if (g_algo->Enable(type) == RET_OK) {
58         DEV_HILOGI(SERVICE, "Success to enable algo module");
59         return RET_OK;
60     }
61     if (g_msdpInterface == nullptr) {
62         g_msdpInterface = GetAlgorithmInst();
63         if (g_msdpInterface == nullptr) {
64             DEV_HILOGI(SERVICE, "get msdp module instance failed");
65             return ERR_NG;
66         }
67     }
68     if (g_msdpInterface->Enable(type) == RET_OK) {
69         DEV_HILOGI(SERVICE, "Success to enable mock module");
70         return RET_OK;
71     }
72     DEV_HILOGI(SERVICE, "Exit");
73     return ERR_NG;
74 }
75 
DisableMsdpImpl(DevicestatusDataUtils::DevicestatusType type)76 ErrCode DevicestatusMsdpClientImpl::DisableMsdpImpl(DevicestatusDataUtils::DevicestatusType type)
77 {
78     DEV_HILOGI(SERVICE, "Enter");
79     std::lock_guard<std::mutex> lock(mutex_);
80     if (g_algo == nullptr) {
81         DEV_HILOGE(SERVICE, "algo object is nullptr");
82         return ERR_NG;
83     }
84     if (g_algo->Disable(type) == RET_OK) {
85         DEV_HILOGI(SERVICE, "Success to disable algo module");
86         return RET_OK;
87     }
88     if (g_msdpInterface == nullptr) {
89         DEV_HILOGE(SERVICE, "disable msdp impl failed");
90         return ERR_NG;
91     }
92     if (g_msdpInterface->Disable(type) == RET_OK) {
93         DEV_HILOGI(SERVICE, "Success to disable mock module");
94         return RET_OK;
95     }
96     DEV_HILOGI(SERVICE, "Exit");
97     return ERR_NG;
98 }
99 
RegisterImpl(const CallbackManager & callback)100 ErrCode DevicestatusMsdpClientImpl::RegisterImpl(const CallbackManager& callback)
101 {
102     DEV_HILOGI(SERVICE, "Enter");
103     std::lock_guard<std::mutex> lock(mutex_);
104     g_callbacksMgr = callback;
105     RegisterMsdp();
106     return ERR_OK;
107 }
108 
UnregisterImpl()109 ErrCode DevicestatusMsdpClientImpl::UnregisterImpl()
110 {
111     DEV_HILOGI(SERVICE, "Enter");
112     std::lock_guard<std::mutex> lock(mutex_);
113     if (g_callbacksMgr == nullptr) {
114         DEV_HILOGI(SERVICE, "unregister callback failed");
115         return ERR_NG;
116     }
117     UnregisterMsdp();
118     g_callbacksMgr = nullptr;
119     return ERR_OK;
120 }
121 
ImplCallback(const DevicestatusDataUtils::DevicestatusData & data)122 ErrCode DevicestatusMsdpClientImpl::ImplCallback(const DevicestatusDataUtils::DevicestatusData& data)
123 {
124     if (g_callbacksMgr == nullptr) {
125         DEV_HILOGI(SERVICE, "g_callbacksMgr is nullptr");
126         return ERR_NG;
127     }
128     g_callbacksMgr(data);
129     return ERR_OK;
130 }
131 
OnResult(const DevicestatusDataUtils::DevicestatusData & data)132 void DevicestatusMsdpClientImpl::OnResult(const DevicestatusDataUtils::DevicestatusData& data)
133 {
134     MsdpCallback(data);
135 }
136 
RegisterMsdp()137 ErrCode DevicestatusMsdpClientImpl::RegisterMsdp()
138 {
139     DEV_HILOGI(SERVICE, "Enter");
140     if (g_algo == nullptr) {
141         DEV_HILOGE(SERVICE, "algo object is nullptr");
142         return ERR_NG;
143     }
144     std::shared_ptr<MsdpAlgorithmCallback> callback = std::make_shared<DevicestatusMsdpClientImpl>();
145     if (g_algo->RegisterCallback(callback) == RET_OK) {
146         DEV_HILOGI(SERVICE, "success register for algo lib");
147         return RET_OK;
148     }
149     if (g_msdpInterface == nullptr) {
150         DEV_HILOGE(SERVICE, "disable msdp impl failed");
151         return ERR_NG;
152     }
153     if (g_msdpInterface->RegisterCallback(callback) == RET_OK) {
154         DEV_HILOGI(SERVICE, "success register for mock lib");
155         return RET_OK;
156     };
157     DEV_HILOGI(SERVICE, "Exit");
158     return ERR_NG;
159 }
160 
UnregisterMsdp(void)161 ErrCode DevicestatusMsdpClientImpl::UnregisterMsdp(void)
162 {
163     DEV_HILOGI(SERVICE, "Enter");
164     if (g_algo == nullptr) {
165         DEV_HILOGE(SERVICE, "algo object is nullptr");
166         return ERR_NG;
167     }
168     if (g_algo->UnregisterCallback() == RET_OK) {
169         DEV_HILOGI(SERVICE, "Success unregister for algo lib");
170         g_algo = nullptr;
171         return RET_OK;
172     }
173     if (g_msdpInterface == nullptr) {
174         DEV_HILOGE(SERVICE, "Unregister callback failed");
175         return ERR_NG;
176     }
177     if (g_msdpInterface->UnregisterCallback() == RET_OK) {
178         DEV_HILOGI(SERVICE, "Success unregister for mock lib");
179         g_msdpInterface = nullptr;
180         return RET_OK;
181     };
182     DEV_HILOGI(SERVICE, "Exit");
183     return ERR_NG;
184 }
185 
MsdpCallback(const DevicestatusDataUtils::DevicestatusData & data)186 int32_t DevicestatusMsdpClientImpl::MsdpCallback(const DevicestatusDataUtils::DevicestatusData& data)
187 {
188     DEV_HILOGI(SERVICE, "Enter");
189     DevicestatusDumper::GetInstance().pushDeviceStatus(data);
190     SaveObserverData(data);
191     if (notifyManagerFlag_) {
192         ImplCallback(data);
193         notifyManagerFlag_ = false;
194     }
195     DEV_HILOGI(SERVICE, "Exit");
196     return ERR_OK;
197 }
198 
SaveObserverData(const DevicestatusDataUtils::DevicestatusData & data)199 DevicestatusDataUtils::DevicestatusData DevicestatusMsdpClientImpl::SaveObserverData(
200     const DevicestatusDataUtils::DevicestatusData& data)
201 {
202     DEV_HILOGI(SERVICE, "Enter");
203     std::lock_guard<std::mutex> lock(mutex_);
204     for (auto iter = g_devicestatusDataMap.begin(); iter != g_devicestatusDataMap.end(); ++iter) {
205         if (iter->first == data.type) {
206             iter->second = data.value;
207             notifyManagerFlag_ = true;
208             return data;
209         }
210     }
211 
212     g_devicestatusDataMap.insert(std::make_pair(data.type, data.value));
213     notifyManagerFlag_ = true;
214 
215     return data;
216 }
217 
GetObserverData() const218 std::map<clientType, clientValue> DevicestatusMsdpClientImpl::GetObserverData() const
219 {
220     DEV_HILOGI(SERVICE, "Enter");
221     return g_devicestatusDataMap;
222 }
223 
LoadAlgorithmLibrary()224 int32_t DevicestatusMsdpClientImpl::LoadAlgorithmLibrary()
225 {
226     DEV_HILOGI(SERVICE, "Enter");
227     if (mAlgorithm_.handle != nullptr) {
228         return ERR_OK;
229     }
230 
231     mAlgorithm_.handle = dlopen(static_cast<std::string>(DEVICESTATUS_MSDP_ALGORITHM_LIB_PATH).c_str(), RTLD_LAZY);
232     if (mAlgorithm_.handle == nullptr) {
233         DEV_HILOGE(SERVICE, "Cannot load library error = %{public}s", dlerror());
234         return ERR_NG;
235     }
236 
237     DEV_HILOGI(SERVICE, "start create pointer");
238     mAlgorithm_.create = (DevicestatusMsdpInterface* (*)()) dlsym(mAlgorithm_.handle, "Create");
239     DEV_HILOGI(SERVICE, "start destroy pointer");
240     mAlgorithm_.destroy = (void *(*)(DevicestatusMsdpInterface*))dlsym(mAlgorithm_.handle, "Destroy");
241 
242     if (mAlgorithm_.create == nullptr || mAlgorithm_.destroy == nullptr) {
243         DEV_HILOGE(SERVICE, "%{public}s dlsym Create or Destroy failed",
244             static_cast<std::string>(DEVICESTATUS_MSDP_ALGORITHM_LIB_PATH).c_str());
245         dlclose(mAlgorithm_.handle);
246         mAlgorithm_.Clear();
247         if (mAlgorithm_.handle == nullptr) {
248             return ERR_OK;
249         }
250         DEV_HILOGE(SERVICE, "Load algo failed");
251         return ERR_NG;
252     }
253 
254     mAlgorithm_.pAlgorithm = mAlgorithm_.create();
255     DEV_HILOGI(SERVICE, "Exit");
256     return ERR_OK;
257 }
258 
UnloadAlgorithmLibrary()259 int32_t DevicestatusMsdpClientImpl::UnloadAlgorithmLibrary()
260 {
261     DEV_HILOGI(SERVICE, "Enter");
262     std::lock_guard<std::mutex> lock(mutex_);
263     if (mAlgorithm_.handle == nullptr) {
264         DEV_HILOGE(SERVICE, "handle is nullptr");
265         return ERR_NG;
266     }
267 
268     if (mAlgorithm_.pAlgorithm != nullptr) {
269         mAlgorithm_.destroy(mAlgorithm_.pAlgorithm);
270         mAlgorithm_.pAlgorithm = nullptr;
271     }
272 
273     dlclose(mAlgorithm_.handle);
274     mAlgorithm_.Clear();
275     DEV_HILOGI(SERVICE, "Exit");
276     return ERR_OK;
277 }
278 
LoadAlgoLib()279 int32_t DevicestatusMsdpClientImpl::LoadAlgoLib()
280 {
281     DEV_HILOGI(SERVICE, "Enter");
282     if (algoHandler_.handle != nullptr) {
283         DEV_HILOGW(SERVICE, "handle has been dlopened");
284         return RET_OK;
285     }
286     algoHandler_.handle = dlopen(ALGO_LIB_PATH.c_str(), RTLD_LAZY);
287     if (algoHandler_.handle == nullptr) {
288         DEV_HILOGE(SERVICE, "Cannot load library error:%{public}s", dlerror());
289         return RET_ERR;
290     }
291     algoHandler_.create = reinterpret_cast<CreateFunc>(dlsym(algoHandler_.handle, "Create"));
292     algoHandler_.destroy = reinterpret_cast<DestroyFunc>(dlsym(algoHandler_.handle, "Destroy"));
293     if (algoHandler_.create == nullptr || algoHandler_.destroy == nullptr) {
294         dlclose(algoHandler_.handle);
295         algoHandler_.Clear();
296         return RET_ERR;
297     }
298     return RET_OK;
299 }
300 
UnloadAlgoLib()301 int32_t DevicestatusMsdpClientImpl::UnloadAlgoLib()
302 {
303    DEV_HILOGI(SERVICE, "Enter");
304     std::lock_guard<std::mutex> lock(mutex_);
305     if (algoHandler_.handle == nullptr) {
306         DEV_HILOGE(SERVICE, "handle is nullptr");
307         return ERR_NG;
308     }
309 
310     if (algoHandler_.pAlgorithm != nullptr) {
311         algoHandler_.destroy(algoHandler_.pAlgorithm);
312         algoHandler_.pAlgorithm = nullptr;
313     }
314 
315     dlclose(algoHandler_.handle);
316     algoHandler_.Clear();
317     DEV_HILOGI(SERVICE, "Exit");
318     return RET_OK;
319 }
320 
GetAlgorithmInst()321 DevicestatusMsdpInterface* DevicestatusMsdpClientImpl::GetAlgorithmInst()
322 {
323     DEV_HILOGI(SERVICE, "Enter");
324     if (mAlgorithm_.handle == nullptr) {
325         DEV_HILOGE(SERVICE, "handle is nullptr");
326         return nullptr;
327     }
328 
329     if (mAlgorithm_.pAlgorithm == nullptr) {
330         std::unique_lock<std::mutex> lock(mutex_);
331         if (mAlgorithm_.pAlgorithm == nullptr) {
332             DEV_HILOGI(SERVICE, "Get mAlgorithm.pAlgorithm");
333             mAlgorithm_.pAlgorithm = mAlgorithm_.create();
334         }
335     }
336 
337     DEV_HILOGI(SERVICE, "Exit");
338     return mAlgorithm_.pAlgorithm;
339 }
340 
GetAlgoObj()341 DevicestatusMsdpInterface* DevicestatusMsdpClientImpl::GetAlgoObj()
342 {
343     DEV_HILOGI(SERVICE, "Enter");
344     if (algoHandler_.handle == nullptr) {
345         DEV_HILOGE(SERVICE, "Algorithm not start");
346         return nullptr;
347     }
348     if (algoHandler_.pAlgorithm == nullptr) {
349         algoHandler_.pAlgorithm = algoHandler_.create();
350     }
351     DEV_HILOGI(SERVICE, "Exit");
352     return algoHandler_.pAlgorithm;
353 }
354 } // namespace Msdp
355 } // namespace OHOS