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 "devhost_service.h"
18 #include "devhost_service_full.h"
19 #include "device_service_stub.h"
20 #include "devsvc_manager_stub.h"
21 #include "hdf_base.h"
22 #include "hdf_log.h"
23 #include "hdf_sbuf.h"
24 #include "osal_mem.h"
25 #include <unistd.h>
26
27 #define HDF_LOG_TAG devsvc_manager_proxy
28
WriteServiceInfo(struct HdfSBuf * data,struct HdfDeviceObject * service,const struct HdfServiceInfo * servInfo)29 static int WriteServiceInfo(
30 struct HdfSBuf *data, struct HdfDeviceObject *service, const struct HdfServiceInfo *servInfo)
31 {
32 int ret = HDF_FAILURE;
33 if (!HdfSbufWriteString(data, servInfo->servName)) {
34 HDF_LOGE("Add service failed, failed to write service name");
35 return ret;
36 }
37
38 if (!HdfSbufWriteUint16(data, servInfo->devClass)) {
39 HDF_LOGE("Add service failed, failed to write devClass");
40 return ret;
41 }
42 if (!HdfSbufWriteUint32(data, servInfo->devId)) {
43 HDF_LOGE("Add service failed, failed to write devId");
44 return ret;
45 }
46 struct HdfDeviceNode *devNode =
47 HDF_SLIST_CONTAINER_OF(struct HdfDeviceObject, service, struct HdfDeviceNode, deviceObject);
48 struct DeviceServiceStub *deviceFullService = (struct DeviceServiceStub *)devNode;
49 if (deviceFullService->remote == NULL) {
50 HDF_LOGE("%{public}s: device service is broken", __func__);
51 return ret;
52 }
53
54 if (HdfSbufWriteRemoteService(data, deviceFullService->remote) != HDF_SUCCESS) {
55 HDF_LOGE("Add service failed, failed to write remote object");
56 return ret;
57 }
58 const char *info = servInfo->servInfo != NULL ? servInfo->servInfo : "";
59 if (!HdfSbufWriteString(data, info)) {
60 HDF_LOGE("Add service failed, failed to write serv info");
61 return HDF_FAILURE;
62 }
63 const char *interfaceDesc = servInfo->interfaceDesc != NULL ? servInfo->interfaceDesc : "";
64 if (!HdfSbufWriteString(data, interfaceDesc)) {
65 HDF_LOGE("Add service failed, failed to write interfaceDesc");
66 return HDF_FAILURE;
67 }
68
69 return HDF_SUCCESS;
70 }
71
DevSvcManagerProxyAddService(struct IDevSvcManager * inst,struct HdfDeviceObject * service,const struct HdfServiceInfo * servInfo)72 static int DevSvcManagerProxyAddService(
73 struct IDevSvcManager *inst, struct HdfDeviceObject *service, const struct HdfServiceInfo *servInfo)
74 {
75 struct DevSvcManagerProxy *serviceProxy = (struct DevSvcManagerProxy *)inst;
76 if (service == NULL || servInfo == NULL || servInfo->servName == NULL) {
77 HDF_LOGE("%{public}s:service or name is null", __func__);
78 return HDF_ERR_INVALID_PARAM;
79 }
80 if ((serviceProxy == NULL) || (serviceProxy->remote == NULL)) {
81 HDF_LOGE("Add service failed, serviceProxy is invalid");
82 return HDF_ERR_INVALID_PARAM;
83 }
84
85 if (servInfo->devClass >= DEVICE_CLASS_MAX) {
86 HDF_LOGE("Add service failed, devClass is invalid");
87 return HDF_ERR_INVALID_PARAM;
88 }
89
90 int status = HDF_FAILURE;
91 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
92 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
93 do {
94 if (data == NULL || reply == NULL) {
95 HDF_LOGE("Add service failed, failed to obtain sbuf");
96 break;
97 }
98 if (!HdfRemoteServiceWriteInterfaceToken(serviceProxy->remote, data) ||
99 WriteServiceInfo(data, service, servInfo) != HDF_SUCCESS) {
100 break;
101 }
102 status =
103 serviceProxy->remote->dispatcher->Dispatch(serviceProxy->remote, DEVSVC_MANAGER_ADD_SERVICE, data, reply);
104 HDF_LOGI("servmgr add service %{public}s, result is %{public}d", servInfo->servName, status);
105 } while (0);
106
107 HdfSbufRecycle(reply);
108 HdfSbufRecycle(data);
109 return status;
110 }
111
DevSvcManagerProxyUpdateService(struct IDevSvcManager * inst,struct HdfDeviceObject * service,const struct HdfServiceInfo * servInfo)112 static int DevSvcManagerProxyUpdateService(struct IDevSvcManager *inst,
113 struct HdfDeviceObject *service, const struct HdfServiceInfo *servInfo)
114 {
115 struct DevSvcManagerProxy *serviceProxy = (struct DevSvcManagerProxy *)inst;
116 if (service == NULL || servInfo == NULL || servInfo->servName == NULL) {
117 HDF_LOGE("%{public}s:service or name is null", __func__);
118 return HDF_ERR_INVALID_PARAM;
119 }
120 if ((serviceProxy == NULL) || (serviceProxy->remote == NULL)) {
121 HDF_LOGE("update service failed, serviceProxy is invalid");
122 return HDF_ERR_INVALID_PARAM;
123 }
124
125 if (servInfo->devClass >= DEVICE_CLASS_MAX) {
126 HDF_LOGE("update service failed, devClass is invalid");
127 return HDF_ERR_INVALID_PARAM;
128 }
129
130 int status = HDF_FAILURE;
131 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
132 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
133 do {
134 if (data == NULL || reply == NULL) {
135 HDF_LOGE("update service failed, failed to obtain sbuf");
136 break;
137 }
138 if (!HdfRemoteServiceWriteInterfaceToken(serviceProxy->remote, data) ||
139 WriteServiceInfo(data, service, servInfo) != HDF_SUCCESS) {
140 break;
141 }
142 status = serviceProxy->remote->dispatcher->Dispatch(
143 serviceProxy->remote, DEVSVC_MANAGER_UPDATE_SERVICE, data, reply);
144 HDF_LOGI("servmgr update service %{public}s, result is %{public}d", servInfo->servName, status);
145 } while (0);
146
147 HdfSbufRecycle(reply);
148 HdfSbufRecycle(data);
149 return status;
150 }
151
DevSvcManagerProxyGetService(struct IDevSvcManager * inst,const char * svcName)152 struct HdfObject *DevSvcManagerProxyGetService(struct IDevSvcManager *inst, const char *svcName)
153 {
154 int status = HDF_FAILURE;
155 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
156 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
157 struct HdfRemoteDispatcher *dispatcher = NULL;
158 struct HdfRemoteService *remoteService = NULL;
159 struct DevSvcManagerProxy *serviceProxy = (struct DevSvcManagerProxy *)inst;
160 do {
161 if ((serviceProxy->remote == NULL) || (data == NULL) || (reply == NULL)) {
162 HDF_LOGE("Get service failed, serviceProxy->remote or data or reply is null");
163 break;
164 }
165 dispatcher = serviceProxy->remote->dispatcher;
166 if (!HdfRemoteServiceWriteInterfaceToken(serviceProxy->remote, data) || !HdfSbufWriteString(data, svcName)) {
167 break;
168 }
169 status = dispatcher->Dispatch(serviceProxy->remote, DEVSVC_MANAGER_GET_SERVICE, data, reply);
170 if (status == HDF_SUCCESS) {
171 remoteService = HdfSbufReadRemoteService(reply);
172 }
173 } while (0);
174
175 HdfSbufRecycle(reply);
176 HdfSbufRecycle(data);
177 HDF_LOGI("DevSvcManagerProxyGetService finish, and status is %{public}d", status);
178 return (remoteService == NULL) ? NULL : &remoteService->object;
179 }
180
DevSvcManagerProxyRemoveService(struct IDevSvcManager * inst,const char * svcName,const struct HdfDeviceObject * devObj)181 void DevSvcManagerProxyRemoveService(struct IDevSvcManager *inst, const char *svcName,
182 const struct HdfDeviceObject *devObj)
183 {
184 (void)devObj;
185 if (inst == NULL || svcName == NULL) {
186 return;
187 }
188 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
189 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
190 struct HdfRemoteDispatcher *dispatcher = NULL;
191 struct HdfRemoteService *remoteService = NULL;
192 struct DevSvcManagerProxy *serviceProxy = (struct DevSvcManagerProxy *)inst;
193
194 do {
195 if ((serviceProxy->remote == NULL) || (data == NULL) || (reply == NULL)) {
196 HDF_LOGE("Remove service failed, serviceProxy->remote or data or reply is null");
197 break;
198 }
199 remoteService = serviceProxy->remote;
200 dispatcher = remoteService->dispatcher;
201 if (!HdfRemoteServiceWriteInterfaceToken(serviceProxy->remote, data) || !HdfSbufWriteString(data, svcName)) {
202 break;
203 }
204 int status = dispatcher->Dispatch(remoteService, DEVSVC_MANAGER_REMOVE_SERVICE, data, reply);
205 HDF_LOGW("Device service manager proxy remove service status is %{public}d", status);
206 } while (0);
207
208 HdfSbufRecycle(reply);
209 HdfSbufRecycle(data);
210 }
211
DevSvcManagerProxyOnRemoteDied(struct HdfDeathRecipient * recipient,struct HdfRemoteService * service)212 static void DevSvcManagerProxyOnRemoteDied(struct HdfDeathRecipient *recipient, struct HdfRemoteService *service)
213 {
214 struct IDevHostService *instance = DevHostServiceNewInstance(0, NULL);
215
216 if (recipient == NULL || service == NULL || instance == NULL) {
217 HDF_LOGE("%{public}s parameter is null", __func__);
218 return;
219 }
220 (void)recipient;
221 struct DevHostServiceFull *fullService = (struct DevHostServiceFull *)instance;
222 struct HdfMessageLooper *looper = &fullService->looper;
223 HDF_LOGW("%{public}s: DevSvcManager dead, host %{public}d stop", __func__, fullService->super.hostId);
224 if ((looper != NULL) && (looper->Stop != NULL)) {
225 looper->Stop(looper);
226 }
227 _exit(0);
228 }
229
DevSvcManagerProxyConstruct(struct DevSvcManagerProxy * inst,struct HdfRemoteService * remote)230 void DevSvcManagerProxyConstruct(struct DevSvcManagerProxy *inst, struct HdfRemoteService *remote)
231 {
232 inst->pvtbl.AddService = DevSvcManagerProxyAddService;
233 inst->pvtbl.UpdateService = DevSvcManagerProxyUpdateService;
234 inst->pvtbl.GetService = DevSvcManagerProxyGetService;
235 inst->pvtbl.RemoveService = DevSvcManagerProxyRemoveService;
236 inst->remote = remote;
237 inst->recipient.OnRemoteDied = DevSvcManagerProxyOnRemoteDied;
238 HdfRemoteServiceAddDeathRecipient(remote, &inst->recipient);
239 }
240
DevSvcManagerProxyObtain(struct HdfRemoteService * remote)241 static struct IDevSvcManager *DevSvcManagerProxyObtain(struct HdfRemoteService *remote)
242 {
243 struct DevSvcManagerProxy *instance = (struct DevSvcManagerProxy *)OsalMemCalloc(sizeof(struct DevSvcManagerProxy));
244 if (instance != NULL) {
245 DevSvcManagerProxyConstruct(instance, remote);
246 }
247 return (struct IDevSvcManager *)instance;
248 }
249
DevSvcManagerProxyCreate(void)250 struct HdfObject *DevSvcManagerProxyCreate(void)
251 {
252 static struct IDevSvcManager *instance = NULL;
253 if (instance == NULL) {
254 struct HdfRemoteService *remote = HdfRemoteServiceGet(DEVICE_SERVICE_MANAGER_SA_ID);
255 if (remote != NULL) {
256 if (!HdfRemoteServiceSetInterfaceDesc(remote, "HDI.IServiceManager.V1_0")) {
257 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
258 HdfRemoteServiceRecycle(remote);
259 return NULL;
260 }
261 instance = DevSvcManagerProxyObtain(remote);
262 }
263 }
264 return (struct HdfObject *)instance;
265 }
266
DevSvcManagerProxyRelease(struct HdfObject * object)267 void DevSvcManagerProxyRelease(struct HdfObject *object)
268 {
269 struct DevSvcManagerProxy *instance = (struct DevSvcManagerProxy *)object;
270 if (instance != NULL) {
271 if (instance->remote != NULL) {
272 HdfRemoteServiceRecycle(instance->remote);
273 instance->remote = NULL;
274 }
275 OsalMemFree(instance);
276 }
277 }
278