• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_proxy.h>
17 #include <devsvc_manager_stub.h>
18 #include <hdf_base.h>
19 #include <hdf_log.h>
20 #include <osal_mem.h>
21 #include "hdf_service_status.h"
22 #include "servmgr_hdi.h"
23 
24 struct HDIServiceManagerClient {
25     struct HDIServiceManager iservmgr;
26     struct HdfRemoteService *remote;
27 };
28 int ServiceStatusListenerMarshalling(struct ServiceStatusListener *listener, struct HdfSBuf *buf);
29 
ServiceManagerHdiCall(struct HDIServiceManagerClient * servMgrClient,int32_t id,struct HdfSBuf * data,struct HdfSBuf * reply)30 static int32_t ServiceManagerHdiCall(struct HDIServiceManagerClient *servMgrClient, int32_t id,
31     struct HdfSBuf *data, struct HdfSBuf *reply)
32 {
33     if (servMgrClient->remote == NULL || servMgrClient->remote->dispatcher == NULL ||
34         servMgrClient->remote->dispatcher->Dispatch == NULL) {
35         return HDF_ERR_INVALID_OBJECT;
36     }
37 
38     return servMgrClient->remote->dispatcher->Dispatch(servMgrClient->remote, id, data, reply);
39 }
40 
HDIServMgrGetService(struct HDIServiceManager * iServMgr,const char * serviceName)41 struct HdfRemoteService *HDIServMgrGetService(struct HDIServiceManager *iServMgr, const char* serviceName)
42 {
43     if (iServMgr == NULL || serviceName == NULL) {
44         return NULL;
45     }
46     struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(iServMgr, struct HDIServiceManagerClient, iservmgr);
47     struct HdfSBuf *data = NULL;
48     struct HdfSBuf *reply = NULL;
49     struct HdfRemoteService *service = NULL;
50 
51     do {
52         data = HdfSbufTypedObtain(SBUF_IPC);
53         reply = HdfSbufTypedObtain(SBUF_IPC);
54         if (data == NULL || reply == NULL) {
55             break;
56         }
57 
58         if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
59             !HdfSbufWriteString(data, serviceName)) {
60             break;
61         }
62         int status = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_GET_SERVICE, data, reply);
63         if (status == HDF_SUCCESS) {
64             service = HdfSbufReadRemoteService(reply);
65         } else {
66             HDF_LOGI("%{public}s: %{public}s not found", __func__, serviceName);
67         }
68     } while (0);
69 
70     if (reply != NULL) {
71         HdfSbufRecycle(reply);
72     }
73     if (data != NULL) {
74         HdfSbufRecycle(data);
75     }
76 
77     return service;
78 }
79 
HDIServMgrRegisterServiceStatusListener(struct HDIServiceManager * self,struct ServiceStatusListener * listener,uint16_t deviceClass)80 int32_t HDIServMgrRegisterServiceStatusListener(struct HDIServiceManager *self,
81     struct ServiceStatusListener *listener, uint16_t deviceClass)
82 {
83     if (self == NULL || listener == NULL) {
84         return HDF_ERR_INVALID_PARAM;
85     }
86     struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(self, struct HDIServiceManagerClient, iservmgr);
87 
88     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
89     if (data == NULL) {
90         return HDF_ERR_MALLOC_FAIL;
91     }
92 
93     if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
94         !HdfSbufWriteUint16(data, deviceClass) ||
95         ServiceStatusListenerMarshalling(listener, data) != HDF_SUCCESS) {
96         HdfSbufRecycle(data);
97         return HDF_FAILURE;
98     }
99 
100     int32_t ret = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_REGISTER_SVCLISTENER, data, NULL);
101     if (ret != HDF_SUCCESS) {
102         HDF_LOGE("failed to register hdi service listener");
103     }
104     HdfSbufRecycle(data);
105     return ret;
106 }
107 
HDIServMgrUnregisterServiceStatusListener(struct HDIServiceManager * self,struct ServiceStatusListener * listener)108 int32_t HDIServMgrUnregisterServiceStatusListener(struct HDIServiceManager *self,
109     struct ServiceStatusListener *listener)
110 {
111     if (self == NULL || listener == NULL) {
112         return HDF_ERR_INVALID_PARAM;
113     }
114     struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(self, struct HDIServiceManagerClient, iservmgr);
115     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
116     if (data == NULL) {
117         return HDF_ERR_MALLOC_FAIL;
118     }
119 
120     if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
121         ServiceStatusListenerMarshalling(listener, data) != HDF_SUCCESS) {
122         HdfSbufRecycle(data);
123         return HDF_FAILURE;
124     }
125 
126     int32_t ret = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_UNREGISTER_SVCLISTENER, data, NULL);
127     if (ret != HDF_SUCCESS) {
128         HDF_LOGE("failed to unregister hdi service listener");
129     }
130     HdfSbufRecycle(data);
131     return ret;
132 }
133 
HDIServiceManagerConstruct(struct HDIServiceManager * inst)134 void HDIServiceManagerConstruct(struct HDIServiceManager *inst)
135 {
136     inst->GetService = HDIServMgrGetService;
137     inst->RegisterServiceStatusListener = HDIServMgrRegisterServiceStatusListener;
138     inst->UnregisterServiceStatusListener = HDIServMgrUnregisterServiceStatusListener;
139 }
140 
HDIServiceManagerGet(void)141 struct HDIServiceManager *HDIServiceManagerGet(void)
142 {
143     struct HdfRemoteService *remote = HdfRemoteServiceGet(DEVICE_SERVICE_MANAGER_SA_ID);
144     if (remote == NULL) {
145         HDF_LOGE("%{public}s: hdi service %{public}s not found", __func__, DEVICE_SERVICE_MANAGER);
146         return NULL;
147     }
148 
149     struct HDIServiceManagerClient *iServMgrClient = OsalMemAlloc(sizeof(struct HDIServiceManagerClient));
150     if (iServMgrClient == NULL) {
151         HDF_LOGE("%{public}s: OOM", __func__);
152         HdfRemoteServiceRecycle(remote);
153         return NULL;
154     }
155     if (!HdfRemoteServiceSetInterfaceDesc(remote, "HDI.IServiceManager.V1_0")) {
156         HDF_LOGE("%{public}s: failed to init interface desc", __func__);
157         HdfRemoteServiceRecycle(remote);
158         OsalMemFree(iServMgrClient);
159         return NULL;
160     }
161     iServMgrClient->remote = remote;
162 
163     HDIServiceManagerConstruct(&iServMgrClient->iservmgr);
164     return &iServMgrClient->iservmgr;
165 }
166 
HDIServiceManagerRelease(struct HDIServiceManager * servmgr)167 void HDIServiceManagerRelease(struct HDIServiceManager *servmgr)
168 {
169     if (servmgr == NULL) {
170         return;
171     }
172     struct HDIServiceManagerClient *iServMgrClient = CONTAINER_OF(servmgr, struct HDIServiceManagerClient, iservmgr);
173     HdfRemoteServiceRecycle(iServMgrClient->remote);
174     OsalMemFree(iServMgrClient);
175 }