• 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_cstring.h"
22 #include "hdf_service_status.h"
23 #include "servmgr_hdi.h"
24 
25 #define SERVICE_LIST_MAX 16
26 
27 struct HDIServiceManagerClient {
28     struct HDIServiceManager iservmgr;
29     struct HdfRemoteService *remote;
30 };
31 int ServiceStatusListenerMarshalling(struct ServiceStatusListener *listener, struct HdfSBuf *buf);
32 
ServiceManagerHdiCall(struct HDIServiceManagerClient * servMgrClient,int32_t id,struct HdfSBuf * data,struct HdfSBuf * reply)33 static int32_t ServiceManagerHdiCall(struct HDIServiceManagerClient *servMgrClient, int32_t id,
34     struct HdfSBuf *data, struct HdfSBuf *reply)
35 {
36     if (servMgrClient->remote == NULL || servMgrClient->remote->dispatcher == NULL ||
37         servMgrClient->remote->dispatcher->Dispatch == NULL) {
38         return HDF_ERR_INVALID_OBJECT;
39     }
40 
41     return servMgrClient->remote->dispatcher->Dispatch(servMgrClient->remote, id, data, reply);
42 }
43 
HdiServiceSetGetInstance(const uint32_t serviceNum)44 static struct HdiServiceSet *HdiServiceSetGetInstance(const uint32_t serviceNum)
45 {
46     struct HdiServiceSet *serviceSet = OsalMemAlloc(sizeof(struct HdiServiceSet));
47     if (serviceSet == NULL) {
48         HDF_LOGE("%{public}s: OOM", __func__);
49         return NULL;
50     }
51     serviceSet->serviceNames = OsalMemCalloc(sizeof(char *) * serviceNum);
52     if (serviceSet->serviceNames == NULL) {
53         HDF_LOGE("%{public}s: OOM", __func__);
54         HdiServiceSetRelease(serviceSet);
55         return NULL;
56     }
57     serviceSet->count = serviceNum;
58     return serviceSet;
59 }
60 
HdiServiceSetUnMarshalling(struct HdfSBuf * buf,struct HdiServiceSet * serviceSet)61 static int32_t HdiServiceSetUnMarshalling(struct HdfSBuf *buf, struct HdiServiceSet *serviceSet)
62 {
63     for (uint32_t i = 0; i < serviceSet->count; i++) {
64         const char *serviceName = HdfSbufReadString(buf);
65         if (serviceName == NULL) {
66             break;
67         }
68         serviceSet->serviceNames[i] = HdfStringCopy(serviceName);
69     }
70 
71     return HDF_SUCCESS;
72 }
73 
HDIServMgrListServiceByInterfaceDesc(struct HDIServiceManager * iServMgr,const char * interfaceDesc)74 struct HdiServiceSet *HDIServMgrListServiceByInterfaceDesc(
75     struct HDIServiceManager *iServMgr, const char *interfaceDesc)
76 {
77     if (iServMgr == NULL || interfaceDesc == NULL || strlen(interfaceDesc) == 0) {
78         return NULL;
79     }
80     struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(iServMgr, struct HDIServiceManagerClient, iservmgr);
81     struct HdiServiceSet *serviceSet = NULL;
82     struct HdfSBuf *data = NULL;
83     struct HdfSBuf *reply = NULL;
84     uint32_t serviceNum = 0;
85 
86     do {
87         data = HdfSbufTypedObtain(SBUF_IPC);
88         reply = HdfSbufTypedObtain(SBUF_IPC);
89         if (data == NULL || reply == NULL) {
90             break;
91         }
92         if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
93             !HdfSbufWriteString(data, interfaceDesc)) {
94             break;
95         }
96         int32_t status =
97             ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC, data, reply);
98         if (status != HDF_SUCCESS) {
99             HDF_LOGE("%{public}s: failed to get %{public}s service collection, the status is %{public}d", __func__,
100                 interfaceDesc, status);
101             break;
102         }
103         if (!HdfSbufReadUint32(reply, &serviceNum)) {
104             break;
105         }
106         if (serviceNum == 0 || serviceNum > SERVICE_LIST_MAX) {
107             break;
108         }
109         serviceSet = HdiServiceSetGetInstance(serviceNum);
110         if (serviceSet == NULL) {
111             break;
112         }
113         HdiServiceSetUnMarshalling(reply, serviceSet);
114     } while (0);
115 
116     HdfSbufRecycle(reply);
117     HdfSbufRecycle(data);
118 
119     return serviceSet;
120 }
121 
HDIServMgrGetService(struct HDIServiceManager * iServMgr,const char * serviceName)122 struct HdfRemoteService *HDIServMgrGetService(struct HDIServiceManager *iServMgr, const char* serviceName)
123 {
124     if (iServMgr == NULL || serviceName == NULL) {
125         return NULL;
126     }
127     struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(iServMgr, struct HDIServiceManagerClient, iservmgr);
128     struct HdfSBuf *data = NULL;
129     struct HdfSBuf *reply = NULL;
130     struct HdfRemoteService *service = NULL;
131 
132     do {
133         data = HdfSbufTypedObtain(SBUF_IPC);
134         reply = HdfSbufTypedObtain(SBUF_IPC);
135         if (data == NULL || reply == NULL) {
136             break;
137         }
138 
139         if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
140             !HdfSbufWriteString(data, serviceName)) {
141             break;
142         }
143         int status = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_GET_SERVICE, data, reply);
144         if (status == HDF_SUCCESS) {
145             service = HdfSbufReadRemoteService(reply);
146         } else {
147             HDF_LOGI("%{public}s: %{public}s not found", __func__, serviceName);
148         }
149     } while (0);
150 
151     HdfSbufRecycle(reply);
152     HdfSbufRecycle(data);
153 
154     return service;
155 }
156 
HDIServMgrRegisterServiceStatusListener(struct HDIServiceManager * self,struct ServiceStatusListener * listener,uint16_t deviceClass)157 int32_t HDIServMgrRegisterServiceStatusListener(struct HDIServiceManager *self,
158     struct ServiceStatusListener *listener, uint16_t deviceClass)
159 {
160     if (self == NULL || listener == NULL) {
161         return HDF_ERR_INVALID_PARAM;
162     }
163     struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(self, struct HDIServiceManagerClient, iservmgr);
164 
165     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
166     if (data == NULL) {
167         return HDF_ERR_MALLOC_FAIL;
168     }
169 
170     if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
171         !HdfSbufWriteUint16(data, deviceClass) ||
172         ServiceStatusListenerMarshalling(listener, data) != HDF_SUCCESS) {
173         HdfSbufRecycle(data);
174         return HDF_FAILURE;
175     }
176 
177     int32_t ret = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_REGISTER_SVCLISTENER, data, NULL);
178     if (ret != HDF_SUCCESS) {
179         HDF_LOGE("failed to register hdi service listener");
180     }
181     HdfSbufRecycle(data);
182     return ret;
183 }
184 
HDIServMgrUnregisterServiceStatusListener(struct HDIServiceManager * self,struct ServiceStatusListener * listener)185 int32_t HDIServMgrUnregisterServiceStatusListener(struct HDIServiceManager *self,
186     struct ServiceStatusListener *listener)
187 {
188     if (self == NULL || listener == NULL) {
189         return HDF_ERR_INVALID_PARAM;
190     }
191     struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(self, struct HDIServiceManagerClient, iservmgr);
192     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
193     if (data == NULL) {
194         return HDF_ERR_MALLOC_FAIL;
195     }
196 
197     if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
198         ServiceStatusListenerMarshalling(listener, data) != HDF_SUCCESS) {
199         HdfSbufRecycle(data);
200         return HDF_FAILURE;
201     }
202 
203     int32_t ret = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_UNREGISTER_SVCLISTENER, data, NULL);
204     if (ret != HDF_SUCCESS) {
205         HDF_LOGE("failed to unregister hdi service listener");
206     }
207     HdfSbufRecycle(data);
208     return ret;
209 }
210 
HDIServiceManagerConstruct(struct HDIServiceManager * inst)211 void HDIServiceManagerConstruct(struct HDIServiceManager *inst)
212 {
213     inst->GetService = HDIServMgrGetService;
214     inst->RegisterServiceStatusListener = HDIServMgrRegisterServiceStatusListener;
215     inst->UnregisterServiceStatusListener = HDIServMgrUnregisterServiceStatusListener;
216     inst->ListServiceByInterfaceDesc = HDIServMgrListServiceByInterfaceDesc;
217 }
218 
HDIServiceManagerGet(void)219 struct HDIServiceManager *HDIServiceManagerGet(void)
220 {
221     struct HdfRemoteService *remote = HdfRemoteServiceGet(DEVICE_SERVICE_MANAGER_SA_ID);
222     if (remote == NULL) {
223         HDF_LOGE("%{public}s: hdi service %{public}s not found", __func__, DEVICE_SERVICE_MANAGER);
224         return NULL;
225     }
226 
227     struct HDIServiceManagerClient *iServMgrClient = OsalMemAlloc(sizeof(struct HDIServiceManagerClient));
228     if (iServMgrClient == NULL) {
229         HDF_LOGE("%{public}s: OOM", __func__);
230         HdfRemoteServiceRecycle(remote);
231         return NULL;
232     }
233     if (!HdfRemoteServiceSetInterfaceDesc(remote, "HDI.IServiceManager.V1_0")) {
234         HDF_LOGE("%{public}s: failed to init interface desc", __func__);
235         HdfRemoteServiceRecycle(remote);
236         OsalMemFree(iServMgrClient);
237         return NULL;
238     }
239     iServMgrClient->remote = remote;
240 
241     HDIServiceManagerConstruct(&iServMgrClient->iservmgr);
242     return &iServMgrClient->iservmgr;
243 }
244 
HDIServiceManagerRelease(struct HDIServiceManager * servmgr)245 void HDIServiceManagerRelease(struct HDIServiceManager *servmgr)
246 {
247     if (servmgr == NULL) {
248         return;
249     }
250     struct HDIServiceManagerClient *iServMgrClient = CONTAINER_OF(servmgr, struct HDIServiceManagerClient, iservmgr);
251     HdfRemoteServiceRecycle(iServMgrClient->remote);
252     OsalMemFree(iServMgrClient);
253 }
254 
HdiServiceSetRelease(struct HdiServiceSet * serviceSet)255 int32_t HdiServiceSetRelease(struct HdiServiceSet *serviceSet)
256 {
257     if (serviceSet == NULL) {
258         return HDF_SUCCESS;
259     }
260     if (serviceSet->count > SERVICE_LIST_MAX) {
261         HDF_LOGE("%{public}s: failed to release serviceSet, serviceSet->count is tainted", __func__);
262         return HDF_FAILURE;
263     }
264     if (serviceSet->serviceNames != NULL) {
265         for (uint32_t i = 0; i < serviceSet->count; i++) {
266             if (serviceSet->serviceNames[i] != NULL) {
267                 OsalMemFree((void *)serviceSet->serviceNames[i]);
268                 serviceSet->serviceNames[i] = NULL;
269             }
270         }
271         OsalMemFree(serviceSet->serviceNames);
272         serviceSet->serviceNames = NULL;
273     }
274     OsalMemFree(serviceSet);
275     return HDF_SUCCESS;
276 }
277