1 /*
2 * Copyright (c) 2020-2023 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_log.h"
10 #include "osal_mem.h"
11 #include "uart_core.h"
12 #include "uart_if.h"
13
14 #define HDF_LOG_TAG uart_servie_c
15 #define UART_RBUF_MALLOC_SIZE_MAX 65535
16
UartIoRead(struct UartHost * host,struct HdfSBuf * data,struct HdfSBuf * reply)17 static int32_t UartIoRead(struct UartHost *host, struct HdfSBuf *data, struct HdfSBuf *reply)
18 {
19 uint32_t len;
20 int32_t ret;
21 uint8_t *buf = NULL;
22
23 if (!HdfSbufReadUint32(data, &len)) {
24 HDF_LOGE("UartIoRead: sbuf read data len fail!");
25 return HDF_ERR_IO;
26 }
27
28 if (len == 0 || len >= UART_RBUF_MALLOC_SIZE_MAX) {
29 HDF_LOGE("UartIoRead: invalid buf len:%u!", len);
30 return HDF_ERR_INVALID_PARAM;
31 }
32
33 buf = (uint8_t *)OsalMemCalloc(len);
34 if (buf == NULL) {
35 HDF_LOGE("UartIoRead: OsalMemCalloc error!");
36 return HDF_ERR_MALLOC_FAIL;
37 }
38
39 ret = UartHostRead(host, buf, len);
40 if (ret < 0) {
41 HDF_LOGE("UartIoRead: Uart host read fail, ret: %d!", ret);
42 OsalMemFree(buf);
43 return HDF_ERR_IO;
44 }
45
46 if (!HdfSbufWriteBuffer(reply, (ret == 0) ? NULL : buf, ret)) {
47 HDF_LOGE("UartIoRead: sbuf write buffer fail!");
48 OsalMemFree(buf);
49 return HDF_ERR_IO;
50 }
51
52 OsalMemFree(buf);
53 return HDF_SUCCESS;
54 }
55
UartIoWrite(struct UartHost * host,struct HdfSBuf * data)56 static int32_t UartIoWrite(struct UartHost *host, struct HdfSBuf *data)
57 {
58 uint32_t size;
59 uint8_t *buf = NULL;
60
61 if (!HdfSbufReadBuffer(data, (const void **)&buf, &size)) {
62 HDF_LOGE("UartIoWrite: sbuf read buffer fail!");
63 return HDF_ERR_IO;
64 }
65 return UartHostWrite(host, buf, size);
66 }
67
UartIoGetBaud(struct UartHost * host,struct HdfSBuf * reply)68 static int32_t UartIoGetBaud(struct UartHost *host, struct HdfSBuf *reply)
69 {
70 int32_t ret;
71 uint32_t baudRate;
72
73 ret = UartHostGetBaud(host, &baudRate);
74 if (ret != HDF_SUCCESS) {
75 HDF_LOGE("UartIoGetBaud: uart get baud fail, ret: %d!", ret);
76 return ret;
77 }
78 if (!HdfSbufWriteUint32(reply, baudRate)) {
79 HDF_LOGE("UartIoGetBaud: sbuf write buffer fail!");
80 return HDF_ERR_IO;
81 }
82 return HDF_SUCCESS;
83 }
84
UartIoSetBaud(struct UartHost * host,struct HdfSBuf * data)85 static int32_t UartIoSetBaud(struct UartHost *host, struct HdfSBuf *data)
86 {
87 uint32_t baudRate;
88
89 if (!HdfSbufReadUint32(data, &baudRate)) {
90 HDF_LOGE("UartIoSetBaud: sbuf read baudRate fail!");
91 return HDF_ERR_IO;
92 }
93 return UartHostSetBaud(host, baudRate);
94 }
95
UartIoGetAttribute(struct UartHost * host,struct HdfSBuf * reply)96 static int32_t UartIoGetAttribute(struct UartHost *host, struct HdfSBuf *reply)
97 {
98 int32_t ret;
99 struct UartAttribute attribute;
100
101 ret = UartHostGetAttribute(host, &attribute);
102 if (ret != HDF_SUCCESS) {
103 HDF_LOGE("UartIoGetAttribute: uart get attribute fail, ret: %d!", ret);
104 return ret;
105 }
106 if (!HdfSbufWriteBuffer(reply, &attribute, sizeof(attribute))) {
107 HDF_LOGE("UartIoGetAttribute: sbuf write attribute fail!");
108 return HDF_ERR_IO;
109 }
110 return HDF_SUCCESS;
111 }
112
UartIoSetAttribute(struct UartHost * host,struct HdfSBuf * data)113 static int32_t UartIoSetAttribute(struct UartHost *host, struct HdfSBuf *data)
114 {
115 uint32_t size;
116 struct UartAttribute *attribute = NULL;
117
118 if (!HdfSbufReadBuffer(data, (const void **)&attribute, &size)) {
119 HDF_LOGE("UartIoSetAttribute: sbuf read buffer fail!");
120 return HDF_ERR_IO;
121 }
122
123 if (size != sizeof(*attribute)) {
124 HDF_LOGE("UartIoSetAttribute: sbuf read size not match, exp:%zu, got:%u!", sizeof(*attribute), size);
125 return HDF_ERR_IO;
126 }
127
128 return UartHostSetAttribute(host, attribute);
129 }
130
UartIoSetTransMode(struct UartHost * host,struct HdfSBuf * data)131 static int32_t UartIoSetTransMode(struct UartHost *host, struct HdfSBuf *data)
132 {
133 uint32_t mode;
134
135 if (!HdfSbufReadUint32(data, &mode)) {
136 HDF_LOGE("UartIoSetTransMode: sbuf read mode fail!");
137 return HDF_ERR_IO;
138 }
139 return UartHostSetTransMode(host, mode);
140 }
141
UartIoDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)142 int32_t UartIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
143 {
144 struct UartHost *host = NULL;
145
146 if (client == NULL) {
147 HDF_LOGE("UartIoDispatch: client is null!");
148 return HDF_ERR_INVALID_OBJECT;
149 }
150
151 if (client->device == NULL) {
152 HDF_LOGE("UartIoDispatch: client->device is null!");
153 return HDF_ERR_INVALID_OBJECT;
154 }
155
156 if (client->device->service == NULL) {
157 HDF_LOGE("UartIoDispatch: client->device->service is null!");
158 return HDF_ERR_INVALID_OBJECT;
159 }
160
161 host = (struct UartHost *)client->device->service;
162 switch (cmd) {
163 case UART_IO_REQUEST:
164 return UartHostRequest(host);
165 case UART_IO_RELEASE:
166 return UartHostRelease(host);
167 case UART_IO_READ:
168 return UartIoRead(host, data, reply);
169 case UART_IO_WRITE:
170 return UartIoWrite(host, data);
171 case UART_IO_GET_BAUD:
172 return UartIoGetBaud(host, reply);
173 case UART_IO_SET_BAUD:
174 return UartIoSetBaud(host, data);
175 case UART_IO_GET_ATTRIBUTE:
176 return UartIoGetAttribute(host, reply);
177 case UART_IO_SET_ATTRIBUTE:
178 return UartIoSetAttribute(host, data);
179 case UART_IO_SET_TRANSMODE:
180 return UartIoSetTransMode(host, data);
181 default:
182 HDF_LOGE("UartIoDispatch: cmd %d is not support!", cmd);
183 return HDF_ERR_NOT_SUPPORT;
184 }
185 }
186