1 /*
2 * Copyright (c) 2021-2022 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 "devsvc_manager_stub.h"
17
18 #ifdef WITH_SELINUX
19 #include <hdf_service_checker.h>
20 #endif
21
22 #include "devmgr_service_stub.h"
23 #include "devsvc_listener_holder.h"
24 #include "devsvc_manager_proxy.h"
25 #include "hdf_cstring.h"
26 #include "hdf_core_log.h"
27 #include "hdf_remote_service.h"
28 #include "hdf_sbuf.h"
29 #include "hdf_slist.h"
30 #include "osal_mem.h"
31 #include "securec.h"
32
33 #define HDF_LOG_TAG devsvc_manager_stub
34
35 // LCOV_EXCL_START
AddServicePermCheck(const char * servName)36 static int32_t AddServicePermCheck(const char *servName)
37 {
38 #ifdef WITH_SELINUX
39 pid_t callingPid = HdfRemoteGetCallingPid();
40 char *callingSid = HdfRemoteGetCallingSid();
41 if (callingSid == NULL) {
42 HDF_LOGE("%{public}s: sid of %{public}d is null", __func__, callingPid);
43 return HDF_ERR_NOPERM;
44 }
45 if (HdfAddServiceCheck(callingSid, servName) != 0) {
46 HDF_LOGE("[selinux] %{public}s %{public}d haven't \"add service\" permission to %{public}s",
47 callingSid, callingPid, servName);
48 free(callingSid);
49 return HDF_ERR_NOPERM;
50 }
51 free(callingSid);
52 #endif
53 return HDF_SUCCESS;
54 }
55
GetServicePermCheck(const char * servName)56 static int32_t GetServicePermCheck(const char *servName)
57 {
58 #ifdef WITH_SELINUX
59 pid_t callingPid = HdfRemoteGetCallingPid();
60 char *callingSid = HdfRemoteGetCallingSid();
61 if (callingSid == NULL) {
62 HDF_LOGE("%{public}s: sid of %{public}d is null", __func__, callingPid);
63 return HDF_ERR_NOPERM;
64 }
65 if (HdfGetServiceCheck(callingSid, servName) != 0) {
66 HDF_LOGE("[selinux] %{public}s %{public}d haven't \"get service\" permission to %{public}s",
67 callingSid, callingPid, servName);
68 free(callingSid);
69 return HDF_ERR_NOPERM;
70 }
71 free(callingSid);
72 #endif
73
74 return HDF_SUCCESS;
75 }
76
ListServicePermCheck(void)77 static int32_t ListServicePermCheck(void)
78 {
79 #ifdef WITH_SELINUX
80 pid_t callingPid = HdfRemoteGetCallingPid();
81 char *callingSid = HdfRemoteGetCallingSid();
82 if (callingSid == NULL) {
83 HDF_LOGE("%{public}s: sid of %{public}d is null", __func__, callingPid);
84 return HDF_ERR_NOPERM;
85 }
86 if (HdfListServiceCheck(callingSid) != 0) {
87 HDF_LOGE("[selinux] %{public}s %{public}d haven't \"list service\" permission", callingSid, callingPid);
88 free(callingSid);
89 return HDF_ERR_NOPERM;
90 }
91 free(callingSid);
92 #endif
93
94 return HDF_SUCCESS;
95 }
96
CheckServiceObjectValidNoLock(const struct DevSvcManagerStub * stub,const struct HdfDeviceObject * service)97 static bool CheckServiceObjectValidNoLock(const struct DevSvcManagerStub *stub, const struct HdfDeviceObject *service)
98 {
99 if (service == NULL) {
100 HDF_LOGW("%{public}s service object is null", __func__);
101 return false;
102 }
103
104 struct HdfSListIterator it;
105 HdfSListIteratorInit(&it, &stub->devObjHolderList);
106 while (HdfSListIteratorHasNext(&it)) {
107 struct HdfSListNode *node = HdfSListIteratorNext(&it);
108 struct HdfDeviceObjectHolder *holder =
109 HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
110
111 if (((uintptr_t)(&holder->devObj) == (uintptr_t)service) && (holder->serviceName != NULL) &&
112 (service->priv != NULL) && (strcmp(holder->serviceName, (char *)service->priv) == 0)) {
113 HDF_LOGD("%{public}s %{public}s service object is valid", __func__, holder->serviceName);
114 return true;
115 }
116 }
117
118 HDF_LOGW("%{public}s service object is invalid", __func__);
119 return false;
120 }
121
CheckRemoteObjectValidNoLock(const struct DevSvcManagerStub * stub,const struct HdfRemoteService * service)122 static bool CheckRemoteObjectValidNoLock(const struct DevSvcManagerStub *stub, const struct HdfRemoteService *service)
123 {
124 if (service == NULL) {
125 HDF_LOGW("%{public}s remote object is null", __func__);
126 return false;
127 }
128
129 struct HdfSListIterator it;
130 HdfSListIteratorInit(&it, &stub->devObjHolderList);
131 while (HdfSListIteratorHasNext(&it)) {
132 struct HdfSListNode *node = HdfSListIteratorNext(&it);
133 struct HdfDeviceObjectHolder *holder =
134 HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
135
136 if (holder->remoteSvcAddr == (uintptr_t)service) {
137 HDF_LOGD("%{public}s remote object is valid", __func__);
138 return true;
139 }
140 }
141
142 HDF_LOGW("%{public}s remote object is invalid", __func__);
143 return false;
144 }
145
ReleaseServiceObjectHolder(struct DevSvcManagerStub * stub,struct HdfDeviceObjectHolder * devObjHolder)146 static void ReleaseServiceObjectHolder(struct DevSvcManagerStub *stub, struct HdfDeviceObjectHolder *devObjHolder)
147 {
148 if (devObjHolder != NULL) {
149 struct HdfDeviceObject *serviceObject = &devObjHolder->devObj;
150 struct HdfRemoteService *serviceRemote = (struct HdfRemoteService *)serviceObject->service;
151 HdfRemoteServiceRemoveDeathRecipient(serviceRemote, &stub->recipient);
152 HdfRemoteServiceRecycle((struct HdfRemoteService *)serviceObject->service);
153 serviceObject->service = NULL;
154 OsalMemFree(serviceObject->priv);
155 serviceObject->priv = NULL;
156 OsalMemFree(devObjHolder->serviceName);
157 devObjHolder->serviceName = NULL;
158 OsalMemFree(devObjHolder);
159 }
160 }
161
ObtainServiceObject(struct DevSvcManagerStub * stub,const char * name,struct HdfRemoteService * service)162 static struct HdfDeviceObject *ObtainServiceObject(
163 struct DevSvcManagerStub *stub, const char *name, struct HdfRemoteService *service)
164 {
165 struct HdfDeviceObjectHolder *serviceObjectHolder = OsalMemCalloc(sizeof(*serviceObjectHolder));
166 if (serviceObjectHolder == NULL) {
167 return NULL;
168 }
169
170 serviceObjectHolder->remoteSvcAddr = (uintptr_t)service;
171 serviceObjectHolder->serviceName = (void *)HdfStringCopy(name);
172 if (serviceObjectHolder->serviceName == NULL) {
173 OsalMemFree(serviceObjectHolder);
174 return NULL;
175 }
176
177 struct HdfDeviceObject *serviceObject = &serviceObjectHolder->devObj;
178 serviceObject->priv = (void *)HdfStringCopy(name);
179 if (serviceObject->priv == NULL) {
180 OsalMemFree(serviceObjectHolder->serviceName);
181 OsalMemFree(serviceObjectHolder);
182 return NULL;
183 }
184 serviceObject->service = (struct IDeviceIoService *)service;
185 service->target = (struct HdfObject *)serviceObject;
186
187 OsalMutexLock(&stub->devSvcStubMutex);
188 HdfSListAdd(&stub->devObjHolderList, &serviceObjectHolder->entry);
189 OsalMutexUnlock(&stub->devSvcStubMutex);
190
191 HdfRemoteServiceAddDeathRecipient(service, &stub->recipient);
192
193 return serviceObject;
194 }
195
ReleaseServiceObject(struct DevSvcManagerStub * stub,struct HdfDeviceObject * serviceObject)196 static void ReleaseServiceObject(struct DevSvcManagerStub *stub, struct HdfDeviceObject *serviceObject)
197 {
198 OsalMutexLock(&stub->devSvcStubMutex);
199 if (serviceObject == NULL) {
200 OsalMutexUnlock(&stub->devSvcStubMutex);
201 return;
202 }
203
204 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
205 OsalMutexUnlock(&stub->devSvcStubMutex);
206 return;
207 }
208
209 struct HdfRemoteService *serviceRemote = (struct HdfRemoteService *)serviceObject->service;
210 HdfRemoteServiceRemoveDeathRecipient(serviceRemote, &stub->recipient);
211
212 struct HdfDeviceObjectHolder *serviceObjectHolder = (struct HdfDeviceObjectHolder *)serviceObject;
213 HdfSListRemove(&stub->devObjHolderList, &serviceObjectHolder->entry);
214 ReleaseServiceObjectHolder(stub, serviceObjectHolder);
215
216 OsalMutexUnlock(&stub->devSvcStubMutex);
217 // LCOV_EXCL_STOP
218 }
219
DevSvcMgrStubGetPara(struct HdfSBuf * data,struct HdfServiceInfo * info,struct HdfRemoteService ** service)220 static int32_t DevSvcMgrStubGetPara(
221 struct HdfSBuf *data, struct HdfServiceInfo *info, struct HdfRemoteService **service)
222 {
223 int ret = HDF_FAILURE;
224 info->servName = HdfSbufReadString(data);
225 if (info->servName == NULL) {
226 HDF_LOGE("%{public}s failed, name is null", __func__);
227 return ret;
228 }
229 ret = AddServicePermCheck(info->servName);
230 if (ret != HDF_SUCCESS) {
231 return ret;
232 }
233
234 info->devClass = DEVICE_CLASS_DEFAULT;
235 if (!HdfSbufReadUint16(data, &info->devClass)) {
236 HDF_LOGE("%{public}s failed, devClass invalid", __func__);
237 return HDF_FAILURE;
238 }
239 if (!HdfSbufReadUint32(data, &info->devId)) {
240 HDF_LOGE("%{public}s failed, devId invalid", __func__);
241 return HDF_FAILURE;
242 }
243
244 *service = HdfSbufReadRemoteService(data);
245 if (*service == NULL) {
246 HDF_LOGE("%{public}s failed, service is null", __func__);
247 return HDF_FAILURE;
248 }
249 info->servInfo = HdfSbufReadString(data);
250 info->interfaceDesc = HdfSbufReadString(data);
251 return HDF_SUCCESS;
252 }
253
DevSvcManagerStubAddService(struct IDevSvcManager * super,struct HdfSBuf * data)254 static int32_t DevSvcManagerStubAddService(struct IDevSvcManager *super, struct HdfSBuf *data)
255 {
256 int ret = HDF_FAILURE;
257 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
258 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
259 HDF_LOGE("%{public}s: invalid interface token", __func__);
260 return HDF_ERR_INVALID_PARAM;
261 }
262 struct HdfServiceInfo info;
263 struct HdfRemoteService *service = NULL;
264 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
265 if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) {
266 return ret;
267 }
268
269 // LCOV_EXCL_START
270 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
271 if (serviceObject == NULL) {
272 return HDF_ERR_MALLOC_FAIL;
273 }
274
275 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
276 ret = super->AddService(super, serviceObject, &info);
277 if (ret != HDF_SUCCESS) {
278 ReleaseServiceObject(stub, serviceObject);
279 } else {
280 ReleaseServiceObject(stub, oldServiceObject);
281 }
282 HDF_LOGI("add service %{public}s, %{public}d", info.servName, ret);
283 return ret;
284 // LCOV_EXCL_STOP
285 }
286
DevSvcManagerStubUpdateService(struct IDevSvcManager * super,struct HdfSBuf * data)287 static int32_t DevSvcManagerStubUpdateService(struct IDevSvcManager *super, struct HdfSBuf *data)
288 {
289 int ret = HDF_FAILURE;
290 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
291 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
292 HDF_LOGE("%{public}s: invalid interface token", __func__);
293 return HDF_ERR_INVALID_PARAM;
294 }
295
296 struct HdfRemoteService *service = NULL;
297 struct HdfServiceInfo info;
298 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
299 if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) {
300 return ret;
301 }
302
303 // LCOV_EXCL_START
304 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
305 if (oldServiceObject == NULL) {
306 HDF_LOGE("update service %{public}s not exist", info.servName);
307 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
308 }
309
310 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
311 if (serviceObject == NULL) {
312 return HDF_ERR_MALLOC_FAIL;
313 }
314
315 ret = super->UpdateService(super, serviceObject, &info);
316 if (ret != HDF_SUCCESS) {
317 ReleaseServiceObject(stub, serviceObject);
318 } else {
319 ReleaseServiceObject(stub, oldServiceObject);
320 }
321 HDF_LOGI("update service %{public}s, %{public}d", info.servName, ret);
322 return ret;
323 // LCOV_EXCL_STOP
324 }
325
DevSvcManagerStubGetService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)326 static int32_t DevSvcManagerStubGetService(struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
327 {
328 int ret = HDF_FAILURE;
329 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
330 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
331 // LCOV_EXCL_START
332 HDF_LOGE("%{public}s: invalid interface token", __func__);
333 return HDF_ERR_INVALID_PARAM;
334 // LCOV_EXCL_STOP
335 }
336 const char *name = HdfSbufReadString(data);
337 if (name == NULL) {
338 // LCOV_EXCL_START
339 HDF_LOGE("%{public}s failed, name is null", __func__);
340 return ret;
341 // LCOV_EXCL_STOP
342 }
343 ret = GetServicePermCheck(name);
344 if (ret != HDF_SUCCESS) {
345 return ret;
346 }
347 struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
348 if (serviceObject == NULL) {
349 HDF_LOGE("StubGetService service %{public}s not found", name);
350 return HDF_FAILURE;
351 }
352
353 // LCOV_EXCL_START
354 const char *svcMgrName = "hdf_device_manager";
355 if (strcmp(name, svcMgrName) != 0) {
356 OsalMutexLock(&stub->devSvcStubMutex);
357 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
358 OsalMutexUnlock(&stub->devSvcStubMutex);
359 HDF_LOGE("StubGetService service %{public}s is invalid", name);
360 return HDF_FAILURE;
361 }
362 }
363 struct HdfRemoteService *remoteService = (struct HdfRemoteService *)serviceObject->service;
364 if (remoteService != NULL) {
365 HdfSbufWriteRemoteService(reply, remoteService);
366 ret = HDF_SUCCESS;
367 HDF_LOGD("StubGetService service %{public}s found!", name);
368 } else {
369 HDF_LOGE("StubGetService %{public}s remoteService is null", name);
370 ret = HDF_FAILURE;
371 }
372
373 if (strcmp(name, svcMgrName) != 0) {
374 OsalMutexUnlock(&stub->devSvcStubMutex);
375 }
376
377 return ret;
378 // LCOV_EXCL_STOP
379 }
380
DevSvcManagerStubListAllService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)381 static int32_t DevSvcManagerStubListAllService(
382 struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
383 {
384 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
385 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
386 HDF_LOGE("%{public}s: invalid interface token", __func__);
387 return HDF_ERR_INVALID_PARAM;
388 }
389 int ret = ListServicePermCheck();
390 if (ret != HDF_SUCCESS) {
391 return ret;
392 }
393 super->ListAllService(super, reply);
394
395 return HDF_SUCCESS;
396 }
397
DevSvcManagerStubListServiceByInterfaceDesc(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)398 static int32_t DevSvcManagerStubListServiceByInterfaceDesc(
399 struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
400 {
401 int ret;
402 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
403 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
404 // LCOV_EXCL_START
405 HDF_LOGE("%{public}s: invalid interface token", __func__);
406 return HDF_ERR_INVALID_PARAM;
407 // LCOV_EXCL_STOP
408 }
409 const char *interfaceDesc = HdfSbufReadString(data);
410 if (interfaceDesc == NULL) {
411 // LCOV_EXCL_START
412 HDF_LOGE("%{public}s failed, interfaceDesc is null", __func__);
413 return HDF_FAILURE;
414 // LCOV_EXCL_STOP
415 }
416 ret = ListServicePermCheck();
417 if (ret != HDF_SUCCESS) {
418 return ret;
419 }
420 ret = super->ListServiceByInterfaceDesc(super, interfaceDesc, reply);
421
422 return ret;
423 }
424
DevSvcManagerStubRemoveService(struct IDevSvcManager * super,struct HdfSBuf * data)425 static int32_t DevSvcManagerStubRemoveService(struct IDevSvcManager *super, struct HdfSBuf *data)
426 {
427 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
428 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
429 // LCOV_EXCL_START
430 HDF_LOGE("%{public}s: invalid interface token", __func__);
431 return HDF_ERR_INVALID_PARAM;
432 // LCOV_EXCL_STOP
433 }
434 const char *name = HdfSbufReadString(data);
435 if (name == NULL) {
436 // LCOV_EXCL_START
437 HDF_LOGE("%{public}s failed, name is null", __func__);
438 return HDF_FAILURE;
439 // LCOV_EXCL_STOP
440 }
441 int32_t ret = AddServicePermCheck(name);
442 if (ret != HDF_SUCCESS) {
443 return ret;
444 }
445 struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
446 if (serviceObject == NULL) {
447 HDF_LOGE("remove service %{public}s not exist", name);
448 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
449 }
450 // LCOV_EXCL_START
451 OsalMutexLock(&stub->devSvcStubMutex);
452 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
453 OsalMutexUnlock(&stub->devSvcStubMutex);
454 HDF_LOGE("StubRemoveService service %{public}s is invalid", name);
455 return HDF_FAILURE;
456 }
457
458 const char *servName = (const char *)serviceObject->priv;
459 if (servName == NULL) {
460 OsalMutexUnlock(&stub->devSvcStubMutex);
461 HDF_LOGE("remove service %{public}s is broken object", name);
462 return HDF_ERR_INVALID_OBJECT;
463 }
464
465 if (strcmp(name, servName) != 0) {
466 OsalMutexUnlock(&stub->devSvcStubMutex);
467 HDF_LOGE("remove service %{public}s name mismatch with %{public}s", name, servName);
468 return HDF_ERR_INVALID_OBJECT;
469 }
470 OsalMutexUnlock(&stub->devSvcStubMutex);
471 super->RemoveService(super, name, serviceObject);
472 HDF_LOGI("service %{public}s removed", name);
473
474 ReleaseServiceObject(stub, serviceObject);
475 return HDF_SUCCESS;
476 // LCOV_EXCL_STOP
477 }
DevSvcManagerStubRegisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)478 static int32_t DevSvcManagerStubRegisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
479 {
480 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
481 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
482 HDF_LOGE("%{public}s: invalid interface token", __func__);
483 return HDF_ERR_INVALID_PARAM;
484 }
485 uint16_t listenClass = DEVICE_CLASS_DEFAULT;
486 if (!HdfSbufReadUint16(data, &listenClass)) {
487 return HDF_ERR_INVALID_PARAM;
488 }
489 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
490 if (listenerRemote == NULL) {
491 return HDF_ERR_INVALID_PARAM;
492 }
493 // LCOV_EXCL_START
494 struct ServStatListenerHolder *listenerHolder =
495 ServStatListenerHolderCreate((uintptr_t)listenerRemote, listenClass);
496 if (listenerHolder == NULL) {
497 HdfRemoteServiceRecycle(listenerRemote);
498 return HDF_ERR_MALLOC_FAIL;
499 }
500
501 int ret = super->RegsterServListener(super, listenerHolder);
502 if (ret != HDF_SUCCESS) {
503 ServStatListenerHolderRelease(listenerHolder);
504 } else {
505 HDF_LOGI("register servstat listener success, pid = %{public}d", HdfRemoteGetCallingPid());
506 }
507
508 return HDF_SUCCESS;
509 // LCOV_EXCL_STOP
510 }
511
DevSvcManagerStubUnregisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)512 static int32_t DevSvcManagerStubUnregisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
513 {
514 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
515 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
516 HDF_LOGE("%{public}s: invalid interface token", __func__);
517 return HDF_ERR_INVALID_PARAM;
518 }
519 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
520 if (listenerRemote == NULL) {
521 return HDF_ERR_INVALID_PARAM;
522 }
523 // LCOV_EXCL_START
524 struct ServStatListenerHolder *listenerHolder = ServStatListenerHolderGet(listenerRemote->index);
525 if (listenerHolder == NULL) {
526 HDF_LOGE("failed to unregister svcstat listener, unknown listener");
527 HdfRemoteServiceRecycle(listenerRemote);
528 return HDF_ERR_INVALID_OBJECT;
529 }
530 super->UnregsterServListener(super, listenerHolder);
531 ServStatListenerHolderRelease(listenerHolder);
532 HdfRemoteServiceRecycle(listenerRemote);
533 HDF_LOGI("unregister servstat listener success");
534 return HDF_SUCCESS;
535 // LCOV_EXCL_STOP
536 }
537
DevSvcManagerStubDispatch(struct HdfRemoteService * service,int code,struct HdfSBuf * data,struct HdfSBuf * reply)538 int DevSvcManagerStubDispatch(struct HdfRemoteService *service, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
539 {
540 int ret = HDF_FAILURE;
541 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)service;
542 if (stub == NULL) {
543 HDF_LOGE("DevSvcManagerStubDispatch failed, object is null, code is %{public}d", code);
544 return ret;
545 }
546 struct IDevSvcManager *super = (struct IDevSvcManager *)&stub->super;
547 HDF_LOGD("DevSvcManagerStubDispatch called: code=%{public}d, calling pid=%{public}d",
548 code, HdfRemoteGetCallingPid());
549 HDF_LOGD("DevSvcManagerStubDispatch called: code=%{public}d, calling uid=%{public}d",
550 code, HdfRemoteGetCallingUid());
551 switch (code) {
552 case DEVSVC_MANAGER_ADD_SERVICE:
553 ret = DevSvcManagerStubAddService(super, data);
554 break;
555 case DEVSVC_MANAGER_UPDATE_SERVICE:
556 ret = DevSvcManagerStubUpdateService(super, data);
557 break;
558 case DEVSVC_MANAGER_GET_SERVICE:
559 ret = DevSvcManagerStubGetService(super, data, reply);
560 break;
561 case DEVSVC_MANAGER_REMOVE_SERVICE:
562 ret = DevSvcManagerStubRemoveService(super, data);
563 break;
564 case DEVSVC_MANAGER_REGISTER_SVCLISTENER:
565 ret = DevSvcManagerStubRegisterServListener(super, data);
566 break;
567 case DEVSVC_MANAGER_UNREGISTER_SVCLISTENER:
568 ret = DevSvcManagerStubUnregisterServListener(super, data);
569 break;
570 case DEVSVC_MANAGER_LIST_ALL_SERVICE:
571 ret = DevSvcManagerStubListAllService(super, data, reply);
572 break;
573 case DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC:
574 ret = DevSvcManagerStubListServiceByInterfaceDesc(super, data, reply);
575 break;
576 default:
577 ret = HdfRemoteServiceDefaultDispatch(stub->remote, code, data, reply);
578 break;
579 }
580 return ret;
581 }
582
583 // LCOV_EXCL_START
DevSvcManagerOnServiceDied(struct HdfDeathRecipient * recipient,struct HdfRemoteService * remote)584 void DevSvcManagerOnServiceDied(struct HdfDeathRecipient *recipient, struct HdfRemoteService *remote)
585 {
586 struct DevSvcManagerStub *stub =
587 HDF_SLIST_CONTAINER_OF(struct HdfDeathRecipient, recipient, struct DevSvcManagerStub, recipient);
588 if (stub == NULL) {
589 return;
590 }
591
592 struct IDevSvcManager *iSvcMgr = &stub->super.super;
593 if (iSvcMgr->GetService == NULL || iSvcMgr->RemoveService == NULL) {
594 HDF_LOGI("%{public}s:invalid svcmgr object", __func__);
595 return;
596 }
597
598 OsalMutexLock(&stub->devSvcStubMutex);
599 if (!CheckRemoteObjectValidNoLock(stub, remote)) {
600 OsalMutexUnlock(&stub->devSvcStubMutex);
601 return;
602 }
603 struct HdfDeviceObject *serviceObject = (struct HdfDeviceObject *)remote->target;
604
605 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
606 OsalMutexUnlock(&stub->devSvcStubMutex);
607 return;
608 }
609
610 char *serviceName = HdfStringCopy((char *)serviceObject->priv);
611 OsalMutexUnlock(&stub->devSvcStubMutex);
612 if (serviceName == NULL) {
613 HDF_LOGI("%{public}s HdfStringCopy fail", __func__);
614 return;
615 }
616
617 HDF_LOGI("service %{public}s died", serviceName);
618 iSvcMgr->RemoveService(iSvcMgr, serviceName, serviceObject);
619
620 ReleaseServiceObject(stub, serviceObject);
621 OsalMemFree(serviceName);
622 }
623 // LCOV_EXCL_STOP
624
DevSvcManagerStubStart(struct IDevSvcManager * svcmgr)625 int DevSvcManagerStubStart(struct IDevSvcManager *svcmgr)
626 {
627 struct DevSvcManagerStub *inst = (struct DevSvcManagerStub *)svcmgr;
628 if (inst == NULL) {
629 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
630 return HDF_ERR_INVALID_PARAM;
631 }
632 if (inst->started) {
633 return HDF_SUCCESS;
634 }
635
636 ServStatListenerHolderinit();
637
638 static struct HdfRemoteDispatcher dispatcher = {.Dispatch = DevSvcManagerStubDispatch};
639 inst->remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher);
640 if (inst->remote == NULL) {
641 // LCOV_EXCL_START
642 HDF_LOGE("failed to obtain device service manager remote service");
643 return HDF_ERR_MALLOC_FAIL;
644 // LCOV_EXCL_STOP
645 }
646 if (!HdfRemoteServiceSetInterfaceDesc(inst->remote, "HDI.IServiceManager.V1_0")) {
647 // LCOV_EXCL_START
648 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
649 HdfRemoteServiceRecycle(inst->remote);
650 return HDF_ERR_INVALID_OBJECT;
651 // LCOV_EXCL_STOP
652 }
653
654 inst->recipient.OnRemoteDied = DevSvcManagerOnServiceDied;
655 int ret = HdfRemoteServiceRegister(DEVICE_SERVICE_MANAGER_SA_ID, inst->remote);
656 if (ret != 0) {
657 HDF_LOGE("failed to publish device service manager, %{public}d", ret);
658 HdfRemoteServiceRecycle(inst->remote);
659 inst->remote = NULL;
660 } else {
661 HDF_LOGI("publish device service manager success");
662 inst->started = true;
663 }
664
665 return ret;
666 }
667
DevSvcManagerStubConstruct(struct DevSvcManagerStub * inst)668 static bool DevSvcManagerStubConstruct(struct DevSvcManagerStub *inst)
669 {
670 if (inst == NULL) {
671 return false;
672 }
673 if (!DevSvcManagerConstruct(&inst->super)) {
674 // LCOV_EXCL_START
675 HDF_LOGE("failed to construct device service manager");
676 return false;
677 // LCOV_EXCL_STOP
678 }
679 inst->super.super.StartService = DevSvcManagerStubStart;
680 OsalMutexInit(&inst->devSvcStubMutex);
681 HdfSListInit(&inst->devObjHolderList);
682
683 return true;
684 }
685
DevSvcManagerStubCreate(void)686 struct HdfObject *DevSvcManagerStubCreate(void)
687 {
688 static struct DevSvcManagerStub *instance;
689 if (instance != NULL) {
690 return (struct HdfObject *)instance;
691 }
692
693 instance = OsalMemCalloc(sizeof(struct DevSvcManagerStub));
694 // LCOV_EXCL_START
695 if (!DevSvcManagerStubConstruct(instance)) {
696 OsalMemFree(instance);
697 instance = NULL;
698 }
699 // LCOV_EXCL_STOP
700 return (struct HdfObject *)instance;
701 }
702
703 // LCOV_EXCL_START
DevObjHolderListReleaseNoLock(struct DevSvcManagerStub * stub)704 static void DevObjHolderListReleaseNoLock(struct DevSvcManagerStub *stub)
705 {
706 struct HdfSListIterator it;
707 HdfSListIteratorInit(&it, &stub->devObjHolderList);
708 while (HdfSListIteratorHasNext(&it)) {
709 struct HdfSListNode *node = HdfSListIteratorNext(&it);
710 HdfSListIteratorRemove(&it);
711 struct HdfDeviceObjectHolder *holder =
712 HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
713
714 ReleaseServiceObjectHolder(stub, holder);
715 }
716 }
717
DevSvcManagerStubRelease(struct HdfObject * object)718 void DevSvcManagerStubRelease(struct HdfObject *object)
719 {
720 struct DevSvcManagerStub *instance = (struct DevSvcManagerStub *)object;
721 if (instance != NULL) {
722 if (instance->remote != NULL) {
723 HdfRemoteServiceRecycle(instance->remote);
724 instance->remote = NULL;
725 }
726 OsalMutexLock(&instance->devSvcStubMutex);
727 DevObjHolderListReleaseNoLock(instance);
728 OsalMutexUnlock(&instance->devSvcStubMutex);
729 OsalMutexDestroy(&instance->devSvcStubMutex);
730 }
731 }
732 // LCOV_EXCL_STOP
733