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 <hdf_device_desc.h>
17 #include <hdf_device_object.h>
18 #include <hdf_log.h>
19 #include <message_parcel.h>
20 #include <osal_mem.h>
21 
22 #include "hdf_sbuf_ipc.h"
23 #include "sample_hdi.h"
24 
25 using OHOS::HDI::Base::SharedMemQueueMeta;
26 
SampleServiceStubPing(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)27 static int32_t SampleServiceStubPing(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
28 {
29     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
30         return HDF_ERR_INVALID_PARAM;
31     }
32     char *outInfo = nullptr;
33     const char *info = HdfSbufReadString(data);
34 
35     int32_t ret = SampleHdiImplInstance()->ping(client->device, info, &outInfo);
36 
37     HdfSbufWriteString(reply, outInfo);
38     OsalMemFree(outInfo);
39     return ret;
40 }
41 
SampleServiceStubSum(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)42 static int32_t SampleServiceStubSum(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
43 {
44     int32_t parm0;
45     int32_t parm1;
46     int32_t result;
47     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
48         return HDF_ERR_INVALID_PARAM;
49     }
50     if (!HdfSbufReadInt32(data, &parm0)) {
51         HDF_LOGE("SampleHdi.sum: miss parm0");
52         return HDF_ERR_INVALID_PARAM;
53     }
54 
55     if (!HdfSbufReadInt32(data, &parm1)) {
56         HDF_LOGE("SampleHdi.sum: miss parm1");
57         return HDF_ERR_INVALID_PARAM;
58     }
59 
60     int32_t ret = SampleHdiImplInstance()->sum(client->device, parm0, parm1, &result);
61     if (ret == HDF_SUCCESS) {
62         if (!HdfSbufWriteInt32(reply, result)) {
63             HDF_LOGE("SampleHdi.sum: failed to write result ");
64             return HDF_FAILURE;
65         }
66     }
67 
68     return ret;
69 }
70 
SampleServiceStubCallback(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)71 static int32_t SampleServiceStubCallback(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
72 {
73     int32_t code;
74     (void)reply;
75     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
76         return HDF_ERR_INVALID_PARAM;
77     }
78     if (!HdfSbufReadInt32(data, &code)) {
79         HDF_LOGE("SampleHdi.callback: miss parameter code");
80         return HDF_ERR_INVALID_PARAM;
81     }
82 
83     struct HdfRemoteService *callback = HdfSbufReadRemoteService(data);
84     if (callback == nullptr) {
85         HDF_LOGE("SampleHdi.callback: miss parameter callback");
86         return HDF_ERR_INVALID_PARAM;
87     }
88     return SampleHdiImplInstance()->callback(client->device, callback, code);
89 }
90 
SampleServiceStubStructTrans(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)91 static int32_t SampleServiceStubStructTrans(
92     struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
93 {
94     HDF_LOGI("SampleServiceStubStructTrans: in");
95     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
96         return HDF_ERR_INVALID_PARAM;
97     }
98     struct DataBlock *dataBlock = DataBlockBlockUnmarshalling(data);
99     if (dataBlock == nullptr) {
100         HDF_LOGE("SampleServiceStubStructTrans: failed to read dataBlock");
101         return HDF_ERR_INVALID_PARAM;
102     }
103 
104     int32_t ret = HDF_SUCCESS;
105     if (!DataBlockBlockMarshalling(dataBlock, reply)) {
106         HDF_LOGE("SampleServiceStubStructTrans: failed to write dataBlock");
107         ret = HDF_ERR_INVALID_PARAM;
108     } else {
109         HDF_LOGI("SampleServiceStubStructTrans: good return");
110     }
111     DataBlockFree(dataBlock);
112     return ret;
113 }
114 
SampleServiceStubBufferTrans(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)115 static int32_t SampleServiceStubBufferTrans(
116     struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
117 {
118     HDF_LOGI("SampleServiceStubBufferTrans: in");
119     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
120         return HDF_ERR_INVALID_PARAM;
121     }
122     constexpr int SAMPLE_TEST_BUFFER_SIZE = 10;
123     const uint8_t *buffer = HdfSbufReadUnpadBuffer(data, SAMPLE_TEST_BUFFER_SIZE);
124     if (buffer == nullptr) {
125         HDF_LOGI("SampleServiceStubBufferTrans: read buffer failed");
126         return HDF_ERR_INVALID_PARAM;
127     }
128 
129     if (!HdfSbufWriteUnpadBuffer(reply, buffer, SAMPLE_TEST_BUFFER_SIZE)) {
130         HDF_LOGE("SampleServiceStubBufferTrans: failed to write buffer");
131         return HDF_ERR_INVALID_PARAM;
132     } else {
133         HDF_LOGI("SampleServiceStubBufferTrans: good return");
134     }
135 
136     return HDF_SUCCESS;
137 }
138 
SampleServiceRegisterDevice(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)139 static int32_t SampleServiceRegisterDevice(
140     struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
141 {
142     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
143         return HDF_ERR_INVALID_PARAM;
144     }
145     (void)reply;
146     const char *deviceName = HdfSbufReadString(data);
147     if (deviceName == nullptr) {
148         return HDF_ERR_INVALID_PARAM;
149     }
150 
151     return SampleHdiImplInstance()->registerDevice(client->device, deviceName);
152 }
153 
SampleServiceUnregisterDevice(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)154 static int32_t SampleServiceUnregisterDevice(
155     struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
156 {
157     (void)reply;
158     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
159         return HDF_ERR_INVALID_PARAM;
160     }
161     const char *deviceName = HdfSbufReadString(data);
162     if (deviceName == nullptr) {
163         return HDF_ERR_INVALID_PARAM;
164     }
165 
166     return SampleHdiImplInstance()->unregisterDevice(client->device, deviceName);
167 }
168 
SampleServiceUpdateDevice(struct HdfDeviceIoClient * client,struct HdfSBuf * data)169 static int32_t SampleServiceUpdateDevice(struct HdfDeviceIoClient *client, struct HdfSBuf *data)
170 {
171     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
172         return HDF_ERR_INVALID_PARAM;
173     }
174     const char *servInfo = HdfSbufReadString(data);
175     if (servInfo == nullptr) {
176         return HDF_ERR_INVALID_PARAM;
177     }
178 
179     return SampleHdiImplInstance()->updateService(client->device, servInfo);
180 }
181 
SampleServiceSmqTrans(struct HdfDeviceIoClient * client,struct HdfSBuf * data)182 static int32_t SampleServiceSmqTrans(struct HdfDeviceIoClient *client, struct HdfSBuf *data)
183 {
184     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
185         return HDF_ERR_INVALID_PARAM;
186     }
187     OHOS::MessageParcel *parcel = nullptr;
188     if (SbufToParcel(data, &parcel) != HDF_SUCCESS) {
189         return HDF_FAILURE;
190     }
191     std::shared_ptr<SharedMemQueueMeta<SampleSmqElement>> smqMeta =
192         SharedMemQueueMeta<SampleSmqElement>::UnMarshalling(*parcel);
193     if (smqMeta == nullptr) {
194         HDF_LOGE("failed to read smq meta form parcel");
195         return HDF_ERR_INVALID_PARAM;
196     }
197 
198     uint32_t element = parcel->ReadUint32();
199 
200     return SampleHdiImplInstance()->tansSmq(client->device, smqMeta.get(), element);
201 }
202 
SampleServiceEndHost(struct HdfDeviceIoClient * client,struct HdfSBuf * data)203 static int32_t SampleServiceEndHost(struct HdfDeviceIoClient *client, struct HdfSBuf *data)
204 {
205     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
206         return HDF_ERR_INVALID_PARAM;
207     }
208 
209     return SampleHdiImplInstance()->endHost(client->device);
210 }
211 
SampleServiceInjectPm(struct HdfDeviceIoClient * client,struct HdfSBuf * data)212 static int32_t SampleServiceInjectPm(struct HdfDeviceIoClient *client, struct HdfSBuf *data)
213 {
214     if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
215         return HDF_ERR_INVALID_PARAM;
216     }
217     return SampleHdiImplInstance()->injectPmState(client->device);
218 }
219 
SampleServiceOnRemoteRequest(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)220 int32_t SampleServiceOnRemoteRequest(
221     struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
222 {
223     HDF_LOGI("SampleServiceDispatch: cmd %{public}d", cmdId);
224     switch (cmdId) {
225         case SAMPLE_SERVICE_PING:
226             return SampleServiceStubPing(client, data, reply);
227         case SAMPLE_SERVICE_SUM:
228             return SampleServiceStubSum(client, data, reply);
229         case SAMPLE_SERVICE_CALLBACK:
230             return SampleServiceStubCallback(client, data, reply);
231         case SAMPLE_STRUCT_TRANS:
232             return SampleServiceStubStructTrans(client, data, reply);
233         case SAMPLE_BUFFER_TRANS:
234             return SampleServiceStubBufferTrans(client, data, reply);
235         case SAMPLE_REGISTER_DEVICE:
236             return SampleServiceRegisterDevice(client, data, reply);
237         case SAMPLE_UNREGISTER_DEVICE:
238             return SampleServiceUnregisterDevice(client, data, reply);
239         case SAMPLE_UPDATE_SERVIE:
240             return SampleServiceUpdateDevice(client, data);
241         case SAMPLE_TRANS_SMQ:
242             return SampleServiceSmqTrans(client, data);
243         case SAMPLE_END_HOST:
244             return SampleServiceEndHost(client, data);
245         case SAMPLE_INJECT_PM:
246             return SampleServiceInjectPm(client, data);
247         default:
248             HDF_LOGE("SampleServiceDispatch: not support cmd %{public}d", cmdId);
249             return HDF_ERR_INVALID_PARAM;
250     }
251 }