• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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