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