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