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_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
AddServicePermCheck(const char * servName)35 static int32_t AddServicePermCheck(const char *servName)
36 {
37 #ifdef WITH_SELINUX
38 pid_t callingPid = HdfRemoteGetCallingPid();
39 char *callingSid = HdfRemoteGetCallingSid();
40 if (callingSid == NULL) {
41 HDF_LOGE("%{public}s: sid of %{public}d is null", __func__, callingPid);
42 return HDF_ERR_NOPERM;
43 }
44 if (HdfAddServiceCheck(callingSid, servName) != 0) {
45 HDF_LOGE("[selinux] %{public}s %{public}d haven't \"add service\" permission to %{public}s",
46 callingSid, callingPid, servName);
47 free(callingSid);
48 return HDF_ERR_NOPERM;
49 }
50 free(callingSid);
51 #endif
52 return HDF_SUCCESS;
53 }
54
GetServicePermCheck(const char * servName)55 static int32_t GetServicePermCheck(const char *servName)
56 {
57 #ifdef WITH_SELINUX
58 pid_t callingPid = HdfRemoteGetCallingPid();
59 char *callingSid = HdfRemoteGetCallingSid();
60 if (callingSid == NULL) {
61 HDF_LOGE("%{public}s: sid of %{public}d is null", __func__, callingPid);
62 return HDF_ERR_NOPERM;
63 }
64 if (HdfGetServiceCheck(callingSid, servName) != 0) {
65 HDF_LOGE("[selinux] %{public}s %{public}d haven't \"get service\" permission to %{public}s",
66 callingSid, callingPid, servName);
67 free(callingSid);
68 return HDF_ERR_NOPERM;
69 }
70 free(callingSid);
71 #endif
72
73 return HDF_SUCCESS;
74 }
75
ListServicePermCheck(void)76 static int32_t ListServicePermCheck(void)
77 {
78 #ifdef WITH_SELINUX
79 pid_t callingPid = HdfRemoteGetCallingPid();
80 char *callingSid = HdfRemoteGetCallingSid();
81 if (callingSid == NULL) {
82 HDF_LOGE("%{public}s: sid of %{public}d is null", __func__, callingPid);
83 return HDF_ERR_NOPERM;
84 }
85 if (HdfListServiceCheck(callingSid) != 0) {
86 HDF_LOGE("[selinux] %{public}s %{public}d haven't \"list service\" permission", callingSid, callingPid);
87 free(callingSid);
88 return HDF_ERR_NOPERM;
89 }
90 free(callingSid);
91 #endif
92
93 return HDF_SUCCESS;
94 }
95
96 // LCOV_EXCL_START
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 }
218 // LCOV_EXCL_STOP
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 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
270 if (serviceObject == NULL) {
271 return HDF_ERR_MALLOC_FAIL;
272 }
273
274 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
275 ret = super->AddService(super, serviceObject, &info);
276 if (ret != HDF_SUCCESS) {
277 ReleaseServiceObject(stub, serviceObject);
278 } else {
279 ReleaseServiceObject(stub, oldServiceObject);
280 }
281 HDF_LOGI("add service %{public}s, %{public}d", info.servName, ret);
282 return ret;
283 }
284
DevSvcManagerStubUpdateService(struct IDevSvcManager * super,struct HdfSBuf * data)285 static int32_t DevSvcManagerStubUpdateService(struct IDevSvcManager *super, struct HdfSBuf *data)
286 {
287 int ret = HDF_FAILURE;
288 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
289 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
290 HDF_LOGE("%{public}s: invalid interface token", __func__);
291 return HDF_ERR_INVALID_PARAM;
292 }
293
294 struct HdfRemoteService *service = NULL;
295 struct HdfServiceInfo info;
296 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
297 if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) {
298 return ret;
299 }
300
301 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
302 if (oldServiceObject == NULL) {
303 HDF_LOGE("update service %{public}s not exist", info.servName);
304 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
305 }
306
307 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
308 if (serviceObject == NULL) {
309 return HDF_ERR_MALLOC_FAIL;
310 }
311
312 ret = super->UpdateService(super, serviceObject, &info);
313 if (ret != HDF_SUCCESS) {
314 ReleaseServiceObject(stub, serviceObject);
315 } else {
316 ReleaseServiceObject(stub, oldServiceObject);
317 }
318 HDF_LOGI("update service %{public}s, %{public}d", info.servName, ret);
319 return ret;
320 }
321
DevSvcManagerStubGetService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)322 static int32_t DevSvcManagerStubGetService(struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
323 {
324 int ret = HDF_FAILURE;
325 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
326 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
327 HDF_LOGE("%{public}s: invalid interface token", __func__);
328 return HDF_ERR_INVALID_PARAM;
329 }
330 const char *name = HdfSbufReadString(data);
331 if (name == NULL) {
332 HDF_LOGE("%{public}s failed, name is null", __func__);
333 return ret;
334 }
335 ret = GetServicePermCheck(name);
336 if (ret != HDF_SUCCESS) {
337 return ret;
338 }
339 struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
340 if (serviceObject == NULL) {
341 HDF_LOGE("StubGetService service %{public}s not found", name);
342 return HDF_FAILURE;
343 }
344
345 const char *svcMgrName = "hdf_device_manager";
346 if (strcmp(name, svcMgrName) != 0) {
347 OsalMutexLock(&stub->devSvcStubMutex);
348 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
349 OsalMutexUnlock(&stub->devSvcStubMutex);
350 HDF_LOGE("StubGetService service %{public}s is invalid", name);
351 return HDF_FAILURE;
352 }
353 }
354 struct HdfRemoteService *remoteService = (struct HdfRemoteService *)serviceObject->service;
355 if (remoteService != NULL) {
356 HdfSbufWriteRemoteService(reply, remoteService);
357 ret = HDF_SUCCESS;
358 HDF_LOGD("StubGetService service %{public}s found!", name);
359 } else {
360 HDF_LOGE("StubGetService %{public}s remoteService is null", name);
361 ret = HDF_FAILURE;
362 }
363
364 if (strcmp(name, svcMgrName) != 0) {
365 OsalMutexUnlock(&stub->devSvcStubMutex);
366 }
367
368 return ret;
369 }
370
DevSvcManagerStubListAllService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)371 static int32_t DevSvcManagerStubListAllService(
372 struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
373 {
374 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
375 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
376 HDF_LOGE("%{public}s: invalid interface token", __func__);
377 return HDF_ERR_INVALID_PARAM;
378 }
379 int ret = ListServicePermCheck();
380 if (ret != HDF_SUCCESS) {
381 return ret;
382 }
383 super->ListAllService(super, reply);
384
385 return HDF_SUCCESS;
386 }
387
DevSvcManagerStubListServiceByInterfaceDesc(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)388 static int32_t DevSvcManagerStubListServiceByInterfaceDesc(
389 struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
390 {
391 int ret;
392 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
393 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
394 HDF_LOGE("%{public}s: invalid interface token", __func__);
395 return HDF_ERR_INVALID_PARAM;
396 }
397 const char *interfaceDesc = HdfSbufReadString(data);
398 if (interfaceDesc == NULL) {
399 HDF_LOGE("%{public}s failed, interfaceDesc is null", __func__);
400 return HDF_FAILURE;
401 }
402 ret = ListServicePermCheck();
403 if (ret != HDF_SUCCESS) {
404 return ret;
405 }
406 ret = super->ListServiceByInterfaceDesc(super, interfaceDesc, reply);
407
408 return ret;
409 }
410
DevSvcManagerStubRemoveService(struct IDevSvcManager * super,struct HdfSBuf * data)411 static int32_t DevSvcManagerStubRemoveService(struct IDevSvcManager *super, struct HdfSBuf *data)
412 {
413 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
414 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
415 HDF_LOGE("%{public}s: invalid interface token", __func__);
416 return HDF_ERR_INVALID_PARAM;
417 }
418 const char *name = HdfSbufReadString(data);
419 if (name == NULL) {
420 HDF_LOGE("%{public}s failed, name is null", __func__);
421 return HDF_FAILURE;
422 }
423 int32_t ret = AddServicePermCheck(name);
424 if (ret != HDF_SUCCESS) {
425 return ret;
426 }
427 struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
428 if (serviceObject == NULL) {
429 HDF_LOGE("remove service %{public}s not exist", name);
430 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
431 }
432
433 OsalMutexLock(&stub->devSvcStubMutex);
434 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
435 OsalMutexUnlock(&stub->devSvcStubMutex);
436 HDF_LOGE("StubRemoveService service %{public}s is invalid", name);
437 return HDF_FAILURE;
438 }
439
440 const char *servName = (const char *)serviceObject->priv;
441 if (servName == NULL) {
442 OsalMutexUnlock(&stub->devSvcStubMutex);
443 HDF_LOGE("remove service %{public}s is broken object", name);
444 return HDF_ERR_INVALID_OBJECT;
445 }
446
447 if (strcmp(name, servName) != 0) {
448 OsalMutexUnlock(&stub->devSvcStubMutex);
449 HDF_LOGE("remove service %{public}s name mismatch with %{public}s", name, servName);
450 return HDF_ERR_INVALID_OBJECT;
451 }
452 OsalMutexUnlock(&stub->devSvcStubMutex);
453 super->RemoveService(super, name, serviceObject);
454 HDF_LOGI("service %{public}s removed", name);
455
456 ReleaseServiceObject(stub, serviceObject);
457 return HDF_SUCCESS;
458 }
DevSvcManagerStubRegisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)459 static int32_t DevSvcManagerStubRegisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
460 {
461 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
462 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
463 HDF_LOGE("%{public}s: invalid interface token", __func__);
464 return HDF_ERR_INVALID_PARAM;
465 }
466 uint16_t listenClass = DEVICE_CLASS_DEFAULT;
467 if (!HdfSbufReadUint16(data, &listenClass)) {
468 return HDF_ERR_INVALID_PARAM;
469 }
470 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
471 if (listenerRemote == NULL) {
472 return HDF_ERR_INVALID_PARAM;
473 }
474
475 struct ServStatListenerHolder *listenerHolder =
476 ServStatListenerHolderCreate((uintptr_t)listenerRemote, listenClass);
477 if (listenerHolder == NULL) {
478 HdfRemoteServiceRecycle(listenerRemote);
479 return HDF_ERR_MALLOC_FAIL;
480 }
481
482 int ret = super->RegsterServListener(super, listenerHolder);
483 if (ret != HDF_SUCCESS) {
484 ServStatListenerHolderRelease(listenerHolder);
485 } else {
486 HDF_LOGI("register servstat listener success, pid = %{public}d", HdfRemoteGetCallingPid());
487 }
488
489 return HDF_SUCCESS;
490 }
491
DevSvcManagerStubUnregisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)492 static int32_t DevSvcManagerStubUnregisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
493 {
494 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
495 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
496 HDF_LOGE("%{public}s: invalid interface token", __func__);
497 return HDF_ERR_INVALID_PARAM;
498 }
499 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
500 if (listenerRemote == NULL) {
501 return HDF_ERR_INVALID_PARAM;
502 }
503 struct ServStatListenerHolder *listenerHolder = ServStatListenerHolderGet(listenerRemote->index);
504 if (listenerHolder == NULL) {
505 HDF_LOGE("failed to unregister svcstat listener, unknown listener");
506 HdfRemoteServiceRecycle(listenerRemote);
507 return HDF_ERR_INVALID_OBJECT;
508 }
509 super->UnregsterServListener(super, listenerHolder);
510 ServStatListenerHolderRelease(listenerHolder);
511 HdfRemoteServiceRecycle(listenerRemote);
512 HDF_LOGI("unregister servstat listener success");
513 return HDF_SUCCESS;
514 }
515
DevSvcManagerStubDispatch(struct HdfRemoteService * service,int code,struct HdfSBuf * data,struct HdfSBuf * reply)516 int DevSvcManagerStubDispatch(struct HdfRemoteService *service, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
517 {
518 int ret = HDF_FAILURE;
519 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)service;
520 if (stub == NULL) {
521 HDF_LOGE("DevSvcManagerStubDispatch failed, object is null, code is %{public}d", code);
522 return ret;
523 }
524 struct IDevSvcManager *super = (struct IDevSvcManager *)&stub->super;
525 HDF_LOGD("DevSvcManagerStubDispatch called: code=%{public}d, calling pid=%{public}d",
526 code, HdfRemoteGetCallingPid());
527 switch (code) {
528 case DEVSVC_MANAGER_ADD_SERVICE:
529 ret = DevSvcManagerStubAddService(super, data);
530 break;
531 case DEVSVC_MANAGER_UPDATE_SERVICE:
532 ret = DevSvcManagerStubUpdateService(super, data);
533 break;
534 case DEVSVC_MANAGER_GET_SERVICE:
535 ret = DevSvcManagerStubGetService(super, data, reply);
536 break;
537 case DEVSVC_MANAGER_REMOVE_SERVICE:
538 ret = DevSvcManagerStubRemoveService(super, data);
539 break;
540 case DEVSVC_MANAGER_REGISTER_SVCLISTENER:
541 ret = DevSvcManagerStubRegisterServListener(super, data);
542 break;
543 case DEVSVC_MANAGER_UNREGISTER_SVCLISTENER:
544 ret = DevSvcManagerStubUnregisterServListener(super, data);
545 break;
546 case DEVSVC_MANAGER_LIST_ALL_SERVICE:
547 ret = DevSvcManagerStubListAllService(super, data, reply);
548 break;
549 case DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC:
550 ret = DevSvcManagerStubListServiceByInterfaceDesc(super, data, reply);
551 break;
552 default:
553 ret = HdfRemoteServiceDefaultDispatch(stub->remote, code, data, reply);
554 break;
555 }
556 return ret;
557 }
558
559 // LCOV_EXCL_START
DevSvcManagerOnServiceDied(struct HdfDeathRecipient * recipient,struct HdfRemoteService * remote)560 void DevSvcManagerOnServiceDied(struct HdfDeathRecipient *recipient, struct HdfRemoteService *remote)
561 {
562 struct DevSvcManagerStub *stub =
563 HDF_SLIST_CONTAINER_OF(struct HdfDeathRecipient, recipient, struct DevSvcManagerStub, recipient);
564 if (stub == NULL) {
565 return;
566 }
567
568 struct IDevSvcManager *iSvcMgr = &stub->super.super;
569 if (iSvcMgr->GetService == NULL || iSvcMgr->RemoveService == NULL) {
570 HDF_LOGI("%{public}s:invalid svcmgr object", __func__);
571 return;
572 }
573
574 OsalMutexLock(&stub->devSvcStubMutex);
575 if (!CheckRemoteObjectValidNoLock(stub, remote)) {
576 OsalMutexUnlock(&stub->devSvcStubMutex);
577 return;
578 }
579 struct HdfDeviceObject *serviceObject = (struct HdfDeviceObject *)remote->target;
580
581 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
582 OsalMutexUnlock(&stub->devSvcStubMutex);
583 return;
584 }
585
586 char *serviceName = HdfStringCopy((char *)serviceObject->priv);
587 OsalMutexUnlock(&stub->devSvcStubMutex);
588 if (serviceName == NULL) {
589 HDF_LOGI("%{public}s HdfStringCopy fail", __func__);
590 return;
591 }
592
593 HDF_LOGI("service %{public}s died", serviceName);
594 iSvcMgr->RemoveService(iSvcMgr, serviceName, serviceObject);
595
596 ReleaseServiceObject(stub, serviceObject);
597 OsalMemFree(serviceName);
598 }
599 // LCOV_EXCL_STOP
600
DevSvcManagerStubStart(struct IDevSvcManager * svcmgr)601 int DevSvcManagerStubStart(struct IDevSvcManager *svcmgr)
602 {
603 struct DevSvcManagerStub *inst = (struct DevSvcManagerStub *)svcmgr;
604 if (inst == NULL) {
605 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
606 return HDF_ERR_INVALID_PARAM;
607 }
608 if (inst->started) {
609 return HDF_SUCCESS;
610 }
611
612 ServStatListenerHolderinit();
613
614 static struct HdfRemoteDispatcher dispatcher = {.Dispatch = DevSvcManagerStubDispatch};
615 inst->remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher);
616 if (inst->remote == NULL) {
617 HDF_LOGE("failed to obtain device service manager remote service");
618 return HDF_ERR_MALLOC_FAIL;
619 }
620 if (!HdfRemoteServiceSetInterfaceDesc(inst->remote, "HDI.IServiceManager.V1_0")) {
621 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
622 HdfRemoteServiceRecycle(inst->remote);
623 return HDF_ERR_INVALID_OBJECT;
624 }
625
626 inst->recipient.OnRemoteDied = DevSvcManagerOnServiceDied;
627 int ret = HdfRemoteServiceRegister(DEVICE_SERVICE_MANAGER_SA_ID, inst->remote);
628 if (ret != 0) {
629 HDF_LOGE("failed to publish device service manager, %{public}d", ret);
630 HdfRemoteServiceRecycle(inst->remote);
631 inst->remote = NULL;
632 } else {
633 HDF_LOGI("publish device service manager success");
634 inst->started = true;
635 }
636
637 return ret;
638 }
639
DevSvcManagerStubConstruct(struct DevSvcManagerStub * inst)640 static bool DevSvcManagerStubConstruct(struct DevSvcManagerStub *inst)
641 {
642 if (inst == NULL) {
643 return false;
644 }
645 if (!DevSvcManagerConstruct(&inst->super)) {
646 HDF_LOGE("failed to construct device service manager");
647 return false;
648 }
649 inst->super.super.StartService = DevSvcManagerStubStart;
650 OsalMutexInit(&inst->devSvcStubMutex);
651 HdfSListInit(&inst->devObjHolderList);
652
653 return true;
654 }
655
DevSvcManagerStubCreate(void)656 struct HdfObject *DevSvcManagerStubCreate(void)
657 {
658 static struct DevSvcManagerStub *instance;
659 if (instance != NULL) {
660 return (struct HdfObject *)instance;
661 }
662
663 instance = OsalMemCalloc(sizeof(struct DevSvcManagerStub));
664 if (!DevSvcManagerStubConstruct(instance)) {
665 OsalMemFree(instance);
666 instance = NULL;
667 }
668
669 return (struct HdfObject *)instance;
670 }
671
672 // LCOV_EXCL_START
DevObjHolderListReleaseNoLock(struct DevSvcManagerStub * stub)673 static void DevObjHolderListReleaseNoLock(struct DevSvcManagerStub *stub)
674 {
675 struct HdfSListIterator it;
676 HdfSListIteratorInit(&it, &stub->devObjHolderList);
677 while (HdfSListIteratorHasNext(&it)) {
678 struct HdfSListNode *node = HdfSListIteratorNext(&it);
679 HdfSListIteratorRemove(&it);
680 struct HdfDeviceObjectHolder *holder =
681 HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
682
683 ReleaseServiceObjectHolder(stub, holder);
684 }
685 }
686
DevSvcManagerStubRelease(struct HdfObject * object)687 void DevSvcManagerStubRelease(struct HdfObject *object)
688 {
689 struct DevSvcManagerStub *instance = (struct DevSvcManagerStub *)object;
690 if (instance != NULL) {
691 if (instance->remote != NULL) {
692 HdfRemoteServiceRecycle(instance->remote);
693 instance->remote = NULL;
694 }
695 OsalMutexLock(&instance->devSvcStubMutex);
696 DevObjHolderListReleaseNoLock(instance);
697 OsalMutexUnlock(&instance->devSvcStubMutex);
698 OsalMutexDestroy(&instance->devSvcStubMutex);
699 }
700 }
701 // LCOV_EXCL_STOP
702