1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdf_io_service_if.h"
10 #include "hdf_log.h"
11 #include "osal_mem.h"
12 #include "securec.h"
13 #include "uart_if.h"
14
15 #define HDF_LOG_TAG uart_if_u_c
16 #define UART_HOST_NAME_LEN 32
17
UartGetObjGetByBusNum(uint32_t num)18 static void *UartGetObjGetByBusNum(uint32_t num)
19 {
20 int ret;
21 char name[UART_HOST_NAME_LEN + 1] = {0};
22
23 ret = snprintf_s(name, UART_HOST_NAME_LEN + 1, UART_HOST_NAME_LEN, "HDF_PLATFORM_UART_%u", num);
24 if (ret < 0) {
25 HDF_LOGE("%s: snprintf_s failed", __func__);
26 return NULL;
27 }
28
29 return (void *)HdfIoServiceBind(name);
30 }
31
UartPutObjByPointer(const void * obj)32 static void UartPutObjByPointer(const void *obj)
33 {
34 if (obj == NULL) {
35 return;
36 }
37 HdfIoServiceRecycle((struct HdfIoService *)obj);
38 };
39
UartOpen(uint32_t port)40 DevHandle UartOpen(uint32_t port)
41 {
42 int32_t ret;
43 void *handle = NULL;
44
45 handle = UartGetObjGetByBusNum(port);
46 if (handle == NULL) {
47 HDF_LOGE("%s: get handle error", __func__);
48 return NULL;
49 }
50
51 struct HdfIoService *service = (struct HdfIoService *)handle;
52 if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
53 HDF_LOGE("%s: service is invalid", __func__);
54 UartPutObjByPointer(handle);
55 return NULL;
56 }
57 ret = service->dispatcher->Dispatch(&service->object, UART_IO_REQUEST, NULL, NULL);
58 if (ret != HDF_SUCCESS) {
59 HDF_LOGE("%s: UartHostRequest error, ret %d", __func__, ret);
60 UartPutObjByPointer(handle);
61 return NULL;
62 }
63
64 return (DevHandle)handle;
65 }
66
UartClose(DevHandle handle)67 void UartClose(DevHandle handle)
68 {
69 int32_t ret;
70
71 if (handle == NULL) {
72 HDF_LOGE("%s: handle is NULL", __func__);
73 return;
74 }
75
76 struct HdfIoService *service = (struct HdfIoService *)handle;
77 if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
78 HDF_LOGE("%s: service is invalid", __func__);
79 UartPutObjByPointer(handle);
80 return;
81 }
82
83 ret = service->dispatcher->Dispatch(&service->object, UART_IO_RELEASE, NULL, NULL);
84 if (ret != HDF_SUCCESS) {
85 HDF_LOGE("%s: UartHostRelease error, ret %d", __func__, ret);
86 }
87 UartPutObjByPointer(handle);
88 }
89
UartDispatch(DevHandle handle,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)90 static int32_t UartDispatch(DevHandle handle, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
91 {
92 int32_t ret;
93 struct HdfIoService *service = (struct HdfIoService *)handle;
94
95 if (service == NULL) {
96 HDF_LOGE("%s: service is null", __func__);
97 return HDF_ERR_INVALID_OBJECT;
98 }
99
100 if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
101 HDF_LOGE("%s: dispatcher is null", __func__);
102 return HDF_ERR_INVALID_PARAM;
103 }
104
105 ret = service->dispatcher->Dispatch(&service->object, cmd, data, reply);
106 if (ret != HDF_SUCCESS) {
107 HDF_LOGE("%s: Dispatch failed: %d", __func__, ret);
108 }
109 return ret;
110 }
111
UartRead(DevHandle handle,uint8_t * buf,uint32_t len)112 int32_t UartRead(DevHandle handle, uint8_t *buf, uint32_t len)
113 {
114 int32_t ret;
115 struct HdfSBuf *data = NULL;
116 struct HdfSBuf *reply = NULL;
117 uint32_t tmpLen;
118 const void *tmpBuf = NULL;
119
120 if (buf == NULL || len == 0) {
121 return HDF_ERR_INVALID_PARAM;
122 }
123
124 data = HdfSbufObtainDefaultSize();
125 if (data == NULL) {
126 HDF_LOGE("%s: failed to obtain data buf", __func__);
127 return HDF_ERR_MALLOC_FAIL;
128 }
129
130 if (!HdfSbufWriteUint32(data, len)) {
131 HDF_LOGE("%s: write read size failed!", __func__);
132 HdfSbufRecycle(data);
133 return HDF_ERR_IO;
134 }
135
136 reply = HdfSbufObtain(len + sizeof(uint64_t));
137 if (reply == NULL) {
138 HDF_LOGE("%s: failed to obtain reply buf", __func__);
139 HdfSbufRecycle(data);
140 return HDF_ERR_MALLOC_FAIL;
141 }
142
143 ret = UartDispatch(handle, UART_IO_READ, data, reply);
144 if (ret != HDF_SUCCESS) {
145 HDF_LOGE("%s: UartDispatch failed: %d", __func__, ret);
146 goto EXIT;
147 }
148
149 if (!HdfSbufReadBuffer(reply, &tmpBuf, &tmpLen)) {
150 HDF_LOGE("%s: sbuf read buffer failed", __func__);
151 ret = HDF_ERR_IO;
152 goto EXIT;
153 }
154
155 if (tmpLen > 0 && memcpy_s(buf, len, tmpBuf, tmpLen) != EOK) {
156 HDF_LOGE("%s: memcpy buf failed", __func__);
157 ret = HDF_ERR_IO;
158 goto EXIT;
159 }
160 ret = tmpLen;
161
162 EXIT:
163 HdfSbufRecycle(data);
164 HdfSbufRecycle(reply);
165 return ret;
166 }
167
UartWrite(DevHandle handle,uint8_t * buf,uint32_t len)168 int32_t UartWrite(DevHandle handle, uint8_t *buf, uint32_t len)
169 {
170 int32_t ret;
171 struct HdfSBuf *data = NULL;
172
173 if (buf == NULL || len == 0) {
174 return HDF_ERR_INVALID_PARAM;
175 }
176
177 data = HdfSbufObtainDefaultSize();
178 if (data == NULL) {
179 HDF_LOGE("%s: failed to obtain write buf", __func__);
180 return HDF_ERR_MALLOC_FAIL;
181 }
182
183 if (!HdfSbufWriteBuffer(data, buf, len)) {
184 HDF_LOGE("%s: sbuf write buffer failed", __func__);
185 HdfSbufRecycle(data);
186 return HDF_ERR_IO;
187 }
188
189 ret = UartDispatch(handle, UART_IO_WRITE, data, NULL);
190 if (ret != HDF_SUCCESS) {
191 HDF_LOGE("%s: UartDispatch failed: %d", __func__, ret);
192 }
193 HdfSbufRecycle(data);
194 return ret;
195 }
196
UartGetBaud(DevHandle handle,uint32_t * baudRate)197 int32_t UartGetBaud(DevHandle handle, uint32_t *baudRate)
198 {
199 int32_t ret;
200 struct HdfSBuf *reply = NULL;
201
202 if (baudRate == NULL) {
203 return HDF_ERR_INVALID_PARAM;
204 }
205
206 reply = HdfSbufObtainDefaultSize();
207 if (reply == NULL) {
208 HDF_LOGE("%s: failed to obtain reply buf", __func__);
209 return HDF_ERR_MALLOC_FAIL;
210 }
211
212 ret = UartDispatch(handle, UART_IO_GET_BAUD, NULL, reply);
213 if (ret != HDF_SUCCESS) {
214 HDF_LOGE("%s: failed to write, ret %d", __func__, ret);
215 HdfSbufRecycle(reply);
216 return ret;
217 }
218
219 if (!HdfSbufReadUint32(reply, baudRate)) {
220 HDF_LOGE("%s: read from reply failed", __func__);
221 ret = HDF_ERR_IO;
222 }
223
224 HdfSbufRecycle(reply);
225 return ret;
226 }
227
UartSetBaud(DevHandle handle,uint32_t baudRate)228 int32_t UartSetBaud(DevHandle handle, uint32_t baudRate)
229 {
230 int32_t ret;
231 struct HdfSBuf *data = NULL;
232
233 data = HdfSbufObtainDefaultSize();
234 if (data == NULL) {
235 HDF_LOGE("%s: failed to obtain data buf", __func__);
236 return HDF_ERR_MALLOC_FAIL;
237 }
238
239 if (!HdfSbufWriteUint32(data, baudRate)) {
240 HDF_LOGE("%s: sbuf write baud rate failed", __func__);
241 HdfSbufRecycle(data);
242 return HDF_ERR_IO;
243 }
244
245 ret = UartDispatch(handle, UART_IO_SET_BAUD, data, NULL);
246 HdfSbufRecycle(data);
247 return ret;
248 }
249
UartGetAttribute(DevHandle handle,struct UartAttribute * attribute)250 int32_t UartGetAttribute(DevHandle handle, struct UartAttribute *attribute)
251 {
252 int32_t ret;
253 struct HdfSBuf *reply = NULL;
254 uint32_t tmpLen;
255 const void *tmpBuf = NULL;
256
257 if (attribute == NULL) {
258 return HDF_ERR_INVALID_PARAM;
259 }
260
261 reply = HdfSbufObtainDefaultSize();
262 if (reply == NULL) {
263 HDF_LOGE("%s: failed to obtain reply buf", __func__);
264 return HDF_ERR_MALLOC_FAIL;
265 }
266
267 ret = UartDispatch(handle, UART_IO_GET_ATTRIBUTE, NULL, reply);
268 if (ret != HDF_SUCCESS) {
269 HDF_LOGE("%s: UartDispatch failed: %d", __func__, ret);
270 HdfSbufRecycle(reply);
271 return HDF_ERR_IO;
272 }
273
274 if (!HdfSbufReadBuffer(reply, &tmpBuf, &tmpLen)) {
275 HDF_LOGE("%s: sbuf read buffer failed", __func__);
276 HdfSbufRecycle(reply);
277 return HDF_ERR_IO;
278 }
279
280 if (tmpLen != sizeof(*attribute)) {
281 HDF_LOGE("%s: reply data len not match, exp:%zu, got:%u", __func__, sizeof(*attribute), tmpLen);
282 HdfSbufRecycle(reply);
283 return HDF_ERR_IO;
284 }
285
286 if (memcpy_s(attribute, sizeof(*attribute), tmpBuf, tmpLen) != EOK) {
287 HDF_LOGE("%s: memcpy buf failed", __func__);
288 HdfSbufRecycle(reply);
289 return HDF_ERR_IO;
290 }
291
292 HdfSbufRecycle(reply);
293 return HDF_SUCCESS;
294 }
295
UartSetAttribute(DevHandle handle,struct UartAttribute * attribute)296 int32_t UartSetAttribute(DevHandle handle, struct UartAttribute *attribute)
297 {
298 int32_t ret;
299 struct HdfSBuf *data = NULL;
300
301 if (attribute == NULL) {
302 return HDF_ERR_INVALID_PARAM;
303 }
304
305 data = HdfSbufObtainDefaultSize();
306 if (data == NULL) {
307 HDF_LOGE("%s: failed to obtain write buf", __func__);
308 return HDF_ERR_MALLOC_FAIL;
309 }
310
311 if (!HdfSbufWriteBuffer(data, (void *)attribute, sizeof(*attribute))) {
312 HDF_LOGE("%s: sbuf write attribute failed", __func__);
313 HdfSbufRecycle(data);
314 return HDF_ERR_IO;
315 }
316
317 ret = UartDispatch(handle, UART_IO_SET_ATTRIBUTE, data, NULL);
318 if (ret != HDF_SUCCESS) {
319 HDF_LOGE("%s: UartDispatch failed: %d", __func__, ret);
320 }
321 HdfSbufRecycle(data);
322 return ret;
323 }
324
UartSetTransMode(DevHandle handle,enum UartTransMode mode)325 int32_t UartSetTransMode(DevHandle handle, enum UartTransMode mode)
326 {
327 int32_t ret;
328 struct HdfSBuf *data = NULL;
329
330 data = HdfSbufObtainDefaultSize();
331 if (data == NULL) {
332 HDF_LOGE("%s: failed to obtain data buf", __func__);
333 return HDF_ERR_MALLOC_FAIL;
334 }
335
336 if (!HdfSbufWriteUint32(data, (uint32_t)mode)) {
337 HDF_LOGE("%s: sbuf write mode failed", __func__);
338 HdfSbufRecycle(data);
339 return HDF_ERR_IO;
340 }
341
342 ret = UartDispatch(handle, UART_IO_SET_TRANSMODE, data, NULL);
343 HdfSbufRecycle(data);
344 return ret;
345 }
346