1 /*
2 * Copyright (c) 2021 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 #include "device_token_proxy.h"
18 #include "devmgr_service_stub.h"
19 #include "devsvc_listener_holder.h"
20 #include "devsvc_manager_proxy.h"
21 #include "hdf_cstring.h"
22 #include "hdf_log.h"
23 #include "hdf_sbuf.h"
24 #include "hdf_slist.h"
25 #include "osal_mem.h"
26
27 #define HDF_LOG_TAG devsvc_manager_stub
28
ObtainServiceObject(struct DevSvcManagerStub * stub,const char * name,struct HdfRemoteService * service)29 static struct HdfDeviceObject *ObtainServiceObject(
30 struct DevSvcManagerStub *stub, const char *name, struct HdfRemoteService *service)
31 {
32 struct HdfDeviceObject *serviceObject = OsalMemCalloc(sizeof(struct HdfDeviceObject));
33 if (serviceObject == NULL) {
34 return NULL;
35 }
36 serviceObject->priv = (void *)HdfStringCopy(name);
37 if (serviceObject->priv == NULL) {
38 OsalMemFree(serviceObject);
39 return NULL;
40 }
41 serviceObject->service = (struct IDeviceIoService *)service;
42 service->target = (struct HdfObject *)serviceObject;
43
44 HdfRemoteServiceAddDeathRecipient(service, &stub->recipient);
45 return serviceObject;
46 }
47
ReleaseServiceObject(struct DevSvcManagerStub * stub,struct HdfDeviceObject * serviceObject)48 static void ReleaseServiceObject(struct DevSvcManagerStub *stub, struct HdfDeviceObject *serviceObject)
49 {
50 if (serviceObject == NULL) {
51 return;
52 }
53 if (serviceObject->priv == NULL) {
54 HDF_LOGW("release service object has empty name, may broken object");
55 return;
56 }
57 struct HdfRemoteService *serviceRemote = (struct HdfRemoteService *)serviceObject->service;
58 HdfRemoteServiceRemoveDeathRecipient(serviceRemote, &stub->recipient);
59 HdfRemoteServiceRecycle((struct HdfRemoteService *)serviceObject->service);
60 OsalMemFree(serviceObject->priv);
61 serviceObject->priv = NULL;
62 serviceObject->service = NULL;
63 OsalMemFree(serviceObject);
64 }
65
DevSvcManagerStubAddService(struct IDevSvcManager * super,struct HdfSBuf * data)66 static int32_t DevSvcManagerStubAddService(struct IDevSvcManager *super, struct HdfSBuf *data)
67 {
68 int ret = HDF_FAILURE;
69 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
70 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
71 HDF_LOGE("%{public}s: invalid interface token", __func__);
72 return HDF_ERR_INVALID_PARAM;
73 }
74 const char *name = HdfSbufReadString(data);
75 if (name == NULL) {
76 HDF_LOGE("%{public}s failed, name is null", __func__);
77 return ret;
78 }
79 uint16_t devClass = DEVICE_CLASS_DEFAULT;
80 if (!HdfSbufReadUint16(data, &devClass)) {
81 HDF_LOGE("%{public}s failed, devClass invalid", __func__);
82 return ret;
83 }
84
85 struct HdfRemoteService *service = HdfSbufReadRemoteService(data);
86 if (service == NULL) {
87 HDF_LOGE("%{public}s failed, service is null", __func__);
88 return ret;
89 }
90 const char *servInfo = HdfSbufReadString(data);
91 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, name, service);
92 if (serviceObject == NULL) {
93 return HDF_ERR_MALLOC_FAIL;
94 }
95
96 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, name);
97 ret = super->AddService(super, name, devClass, serviceObject, servInfo);
98 if (ret != HDF_SUCCESS) {
99 ReleaseServiceObject(stub, serviceObject);
100 } else {
101 ReleaseServiceObject(stub, oldServiceObject);
102 }
103 HDF_LOGI("add service %{public}s, %{public}d", name, ret);
104 return ret;
105 }
106
DevSvcManagerStubUpdateService(struct IDevSvcManager * super,struct HdfSBuf * data)107 static int32_t DevSvcManagerStubUpdateService(struct IDevSvcManager *super, struct HdfSBuf *data)
108 {
109 int ret = HDF_FAILURE;
110 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
111 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
112 HDF_LOGE("%{public}s: invalid interface token", __func__);
113 return HDF_ERR_INVALID_PARAM;
114 }
115 const char *name = HdfSbufReadString(data);
116 if (name == NULL) {
117 HDF_LOGE("%{public}s failed, name is null", __func__);
118 return ret;
119 }
120 uint16_t devClass = DEVICE_CLASS_DEFAULT;
121 if (!HdfSbufReadUint16(data, &devClass)) {
122 HDF_LOGE("%{public}s failed, devClass invalid", __func__);
123 return ret;
124 }
125
126 struct HdfRemoteService *service = HdfSbufReadRemoteService(data);
127 if (service == NULL) {
128 HDF_LOGE("%{public}s failed, remote service is null", __func__);
129 return ret;
130 }
131 const char *servInfo = HdfSbufReadString(data);
132
133 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, name);
134 if (oldServiceObject == NULL) {
135 HDF_LOGE("update service %{public}s not exist", name);
136 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
137 }
138
139 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, name, service);
140 if (serviceObject == NULL) {
141 return HDF_ERR_MALLOC_FAIL;
142 }
143
144 ret = super->UpdateService(super, name, devClass, serviceObject, servInfo);
145 if (ret != HDF_SUCCESS) {
146 ReleaseServiceObject(stub, serviceObject);
147 } else {
148 ReleaseServiceObject(stub, oldServiceObject);
149 }
150 HDF_LOGI("update service %{public}s, %{public}d", name, ret);
151 return ret;
152 }
153
DevSvcManagerStubGetService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)154 static int32_t DevSvcManagerStubGetService(struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
155 {
156 int ret = HDF_FAILURE;
157 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
158 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
159 HDF_LOGE("%{public}s: invalid interface token", __func__);
160 return HDF_ERR_INVALID_PARAM;
161 }
162 const char *name = HdfSbufReadString(data);
163 if (name == NULL) {
164 HDF_LOGE("%{public}s failed, name is null", __func__);
165 return ret;
166 }
167 struct HdfRemoteService *remoteService = (struct HdfRemoteService *)super->GetService(super, name);
168 if (remoteService != NULL) {
169 ret = HDF_SUCCESS;
170 HdfSbufWriteRemoteService(reply, remoteService);
171 HDF_LOGI("service %{public}s found", name);
172 } else {
173 HDF_LOGE("service %{public}s not found", name);
174 }
175
176 return ret;
177 }
178
DevSvcManagerStubRemoveService(struct IDevSvcManager * super,struct HdfSBuf * data)179 static int32_t DevSvcManagerStubRemoveService(struct IDevSvcManager *super, struct HdfSBuf *data)
180 {
181 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
182 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
183 HDF_LOGE("%{public}s: invalid interface token", __func__);
184 return HDF_ERR_INVALID_PARAM;
185 }
186 const char *name = HdfSbufReadString(data);
187 if (name == NULL) {
188 HDF_LOGE("%{public}s failed, name is null", __func__);
189 return HDF_FAILURE;
190 }
191 struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
192 if (serviceObject == NULL) {
193 HDF_LOGE("remove service %{public}s not exist", name);
194 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
195 }
196
197 const char *servName = (const char *)serviceObject->priv;
198 if (servName == NULL) {
199 HDF_LOGE("remove service %{public}s is broken object", name);
200 return HDF_ERR_INVALID_OBJECT;
201 }
202
203 if (strcmp(name, servName) != 0) {
204 HDF_LOGE("remove service %{public}s name mismatch with %{public}s", name, servName);
205 return HDF_ERR_INVALID_OBJECT;
206 }
207
208 super->RemoveService(super, name);
209 HDF_LOGI("service %{public}s removed", name);
210
211 ReleaseServiceObject(stub, serviceObject);
212 return HDF_SUCCESS;
213 }
DevSvcManagerStubRegisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)214 static int32_t DevSvcManagerStubRegisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
215 {
216 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
217 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
218 HDF_LOGE("%{public}s: invalid interface token", __func__);
219 return HDF_ERR_INVALID_PARAM;
220 }
221 uint16_t listenClass = DEVICE_CLASS_DEFAULT;
222 if (!HdfSbufReadUint16(data, &listenClass)) {
223 return HDF_ERR_INVALID_PARAM;
224 }
225 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
226 if (listenerRemote == NULL) {
227 return HDF_ERR_INVALID_PARAM;
228 }
229
230 struct ServStatListenerHolder *listenerHolder =
231 ServStatListenerHolderCreate((uintptr_t)listenerRemote, listenClass);
232 if (listenerHolder == NULL) {
233 return HDF_ERR_MALLOC_FAIL;
234 }
235
236 int ret = super->RegsterServListener(super, listenerHolder);
237 if (ret != HDF_SUCCESS) {
238 ServStatListenerHolderRelease(listenerHolder);
239 } else {
240 HDF_LOGI("register servstat listener success");
241 }
242
243 return HDF_SUCCESS;
244 }
245
DevSvcManagerStubUnregisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)246 static int32_t DevSvcManagerStubUnregisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
247 {
248 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
249 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
250 HDF_LOGE("%{public}s: invalid interface token", __func__);
251 return HDF_ERR_INVALID_PARAM;
252 }
253 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
254 if (listenerRemote == NULL) {
255 return HDF_ERR_INVALID_PARAM;
256 }
257 struct ServStatListenerHolder *listenerHolder = ServStatListenerHolderGet(listenerRemote->index);
258 if (listenerHolder == NULL) {
259 HDF_LOGE("failed to unregister svcstat listener, unknown listener");
260 HdfRemoteServiceRecycle(listenerRemote);
261 return HDF_ERR_INVALID_OBJECT;
262 }
263 super->UnregsterServListener(super, listenerHolder);
264 ServStatListenerHolderRelease(listenerHolder);
265 HdfRemoteServiceRecycle(listenerRemote);
266 HDF_LOGI("unregister servstat listener success");
267 return HDF_SUCCESS;
268 }
269
DevSvcManagerStubDispatch(struct HdfRemoteService * service,int code,struct HdfSBuf * data,struct HdfSBuf * reply)270 int DevSvcManagerStubDispatch(struct HdfRemoteService *service, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
271 {
272 int ret = HDF_FAILURE;
273 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)service;
274 if (stub == NULL) {
275 HDF_LOGE("DevSvcManagerStubDispatch failed, object is null, code is %{public}d", code);
276 return ret;
277 }
278 struct IDevSvcManager *super = (struct IDevSvcManager *)&stub->super;
279 HDF_LOGD("DevSvcManagerStubDispatch called: code=%{public}d", code);
280 switch (code) {
281 case DEVSVC_MANAGER_ADD_SERVICE:
282 ret = DevSvcManagerStubAddService(super, data);
283 break;
284 case DEVSVC_MANAGER_UPDATE_SERVICE:
285 ret = DevSvcManagerStubUpdateService(super, data);
286 break;
287 case DEVSVC_MANAGER_GET_SERVICE:
288 ret = DevSvcManagerStubGetService(super, data, reply);
289 break;
290 case DEVSVC_MANAGER_REMOVE_SERVICE:
291 ret = DevSvcManagerStubRemoveService(super, data);
292 break;
293 case DEVSVC_MANAGER_REGISER_SVCLISTENER:
294 ret = DevSvcManagerStubRegisterServListener(super, data);
295 break;
296 case DEVSVC_MANAGER_UNREGISER_SVCLISTENER:
297 ret = DevSvcManagerStubUnregisterServListener(super, data);
298 break;
299 default:
300 HDF_LOGE("Unknown code : %{public}d", code);
301 ret = HDF_FAILURE;
302 }
303 return ret;
304 }
305
DevSvcManagerOnServiceDied(struct HdfDeathRecipient * recipient,struct HdfRemoteService * remote)306 void DevSvcManagerOnServiceDied(struct HdfDeathRecipient *recipient, struct HdfRemoteService *remote)
307 {
308 struct DevSvcManagerStub *stub =
309 HDF_SLIST_CONTAINER_OF(struct HdfDeathRecipient, recipient, struct DevSvcManagerStub, recipient);
310 if (stub == NULL) {
311 return;
312 }
313
314 struct IDevSvcManager *iSvcMgr = &stub->super.super;
315 struct HdfDeviceObject *serviceObject = (struct HdfDeviceObject *)remote->target;
316
317 if (serviceObject == NULL || serviceObject->priv == NULL) {
318 HDF_LOGI("%{public}s:invalid service object", __func__);
319 return;
320 }
321
322 if (iSvcMgr->GetService == NULL || iSvcMgr->RemoveService == NULL) {
323 HDF_LOGI("%{public}s:invalid svcmgr object", __func__);
324 return;
325 }
326
327 char *serviceName = (char *)serviceObject->priv;
328 struct HdfObject *service = iSvcMgr->GetService(iSvcMgr, serviceName);
329 HDF_LOGI("service %{public}s died", serviceName);
330
331 if ((uintptr_t)service == (uintptr_t)remote) {
332 HDF_LOGI("%{public}s: remove died service %{public}s", __func__, serviceName);
333 iSvcMgr->RemoveService(iSvcMgr, serviceName);
334 }
335
336 ReleaseServiceObject(stub, serviceObject);
337 }
338
DevSvcManagerStubStart(struct IDevSvcManager * svcmgr)339 int DevSvcManagerStubStart(struct IDevSvcManager *svcmgr)
340 {
341 struct DevSvcManagerStub *inst = (struct DevSvcManagerStub *)svcmgr;
342 if (inst == NULL) {
343 return HDF_ERR_INVALID_PARAM;
344 }
345 if (inst->started) {
346 return HDF_SUCCESS;
347 }
348
349 ServStatListenerHolderinit();
350
351 static struct HdfRemoteDispatcher dispatcher = {.Dispatch = DevSvcManagerStubDispatch};
352 inst->remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher);
353 if (inst->remote == NULL) {
354 HDF_LOGE("failed to obtain device service manager remote service");
355 return HDF_ERR_MALLOC_FAIL;
356 }
357 if (!HdfRemoteServiceSetInterfaceDesc(inst->remote, "HDI.IServiceManager.V1_0")) {
358 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
359 return HDF_ERR_INVALID_OBJECT;
360 }
361
362 inst->recipient.OnRemoteDied = DevSvcManagerOnServiceDied;
363 int ret = HdfRemoteServiceRegister(DEVICE_SERVICE_MANAGER_SA_ID, inst->remote);
364 if (ret != 0) {
365 HDF_LOGE("failed to publish device service manager, %{public}d", ret);
366 HdfRemoteServiceRecycle(inst->remote);
367 inst->remote = NULL;
368 } else {
369 HDF_LOGI("publish device service manager success");
370 inst->started = true;
371 }
372
373 return ret;
374 }
375
DevSvcManagerStubConstruct(struct DevSvcManagerStub * inst)376 static bool DevSvcManagerStubConstruct(struct DevSvcManagerStub *inst)
377 {
378 if (inst == NULL) {
379 return false;
380 }
381 if (!DevSvcManagerConstruct(&inst->super)) {
382 HDF_LOGE("failed to construct device service manager");
383 return false;
384 }
385 inst->super.super.StartService = DevSvcManagerStubStart;
386
387 return true;
388 }
389
DevSvcManagerStubCreate(void)390 struct HdfObject *DevSvcManagerStubCreate(void)
391 {
392 static struct DevSvcManagerStub *instance;
393 if (instance != NULL) {
394 return (struct HdfObject *)instance;
395 }
396
397 instance = OsalMemCalloc(sizeof(struct DevSvcManagerStub));
398 if (!DevSvcManagerStubConstruct(instance)) {
399 OsalMemFree(instance);
400 instance = NULL;
401 }
402
403 return (struct HdfObject *)instance;
404 }
405
DevSvcManagerStubRelease(struct HdfObject * object)406 void DevSvcManagerStubRelease(struct HdfObject *object)
407 {
408 struct DevmgrServiceStub *instance = (struct DevmgrServiceStub *)object;
409 if (instance != NULL) {
410 if (instance->remote != NULL) {
411 HdfRemoteServiceRecycle(instance->remote);
412 instance->remote = NULL;
413 }
414 }
415 }
416