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