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_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 return HDF_FAILURE;
97 }
98
99 int32_t ret = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_REGISER_SVCLISTENER, data, NULL);
100 if (ret != HDF_SUCCESS) {
101 HDF_LOGE("failed to register hdi service listener");
102 }
103 HdfSbufRecycle(data);
104 return ret;
105 }
106
HDIServMgrUnregisterServiceStatusListener(struct HDIServiceManager * self,struct ServiceStatusListener * listener)107 int32_t HDIServMgrUnregisterServiceStatusListener(struct HDIServiceManager *self,
108 struct ServiceStatusListener *listener)
109 {
110 if (self == NULL || listener == NULL) {
111 return HDF_ERR_INVALID_PARAM;
112 }
113 struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(self, struct HDIServiceManagerClient, iservmgr);
114 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
115 if (data == NULL) {
116 return HDF_ERR_MALLOC_FAIL;
117 }
118
119 if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) ||
120 ServiceStatusListenerMarshalling(listener, data) != HDF_SUCCESS) {
121 return HDF_FAILURE;
122 }
123
124 int32_t ret = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_UNREGISER_SVCLISTENER, data, NULL);
125 if (ret != HDF_SUCCESS) {
126 HDF_LOGE("failed to unregister hdi service listener");
127 }
128 HdfSbufRecycle(data);
129 return ret;
130 }
131
HDIServiceManagerConstruct(struct HDIServiceManager * inst)132 void HDIServiceManagerConstruct(struct HDIServiceManager *inst)
133 {
134 inst->GetService = HDIServMgrGetService;
135 inst->RegisterServiceStatusListener = HDIServMgrRegisterServiceStatusListener;
136 inst->UnregisterServiceStatusListener = HDIServMgrUnregisterServiceStatusListener;
137 }
138
HDIServiceManagerGet(void)139 struct HDIServiceManager *HDIServiceManagerGet(void)
140 {
141 struct HdfRemoteService *remote = HdfRemoteServiceGet(DEVICE_SERVICE_MANAGER_SA_ID);
142 if (remote == NULL) {
143 HDF_LOGE("%{public}s: hdi service %{public}s not found", __func__, DEVICE_SERVICE_MANAGER);
144 return NULL;
145 }
146
147 struct HDIServiceManagerClient *iServMgrClient = OsalMemAlloc(sizeof(struct HDIServiceManagerClient));
148 if (iServMgrClient == NULL) {
149 HDF_LOGE("%{public}s: OOM", __func__);
150 HdfRemoteServiceRecycle(remote);
151 return NULL;
152 }
153 if (!HdfRemoteServiceSetInterfaceDesc(remote, "HDI.IServiceManager.V1_0")) {
154 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
155 HdfRemoteServiceRecycle(remote);
156 return NULL;
157 }
158 iServMgrClient->remote = remote;
159
160 HDIServiceManagerConstruct(&iServMgrClient->iservmgr);
161 return &iServMgrClient->iservmgr;
162 }
163
HDIServiceManagerRelease(struct HDIServiceManager * servmgr)164 void HDIServiceManagerRelease(struct HDIServiceManager *servmgr)
165 {
166 if (servmgr == NULL) {
167 return;
168 }
169 struct HDIServiceManagerClient *iServMgrClient = CONTAINER_OF(servmgr, struct HDIServiceManagerClient, iservmgr);
170 HdfRemoteServiceRecycle(iServMgrClient->remote);
171 OsalMemFree(iServMgrClient);
172 }