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