1 /*
2 * Copyright (c) 2020-2021 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("%s: sbuf read data len failed", __func__);
25 return HDF_ERR_IO;
26 }
27
28 if (len == 0 || len >= UART_RBUF_MALLOC_SIZE_MAX) {
29 HDF_LOGE("%s: invalid buf len:%u", __func__, len);
30 return HDF_ERR_INVALID_PARAM;
31 }
32
33 buf = (uint8_t *)OsalMemCalloc(len);
34 if (buf == NULL) {
35 HDF_LOGE("%s: OsalMemCalloc error", __func__);
36 return HDF_ERR_MALLOC_FAIL;
37 }
38
39 ret = UartHostRead(host, buf, len);
40 if (ret < 0) {
41 HDF_LOGE("%s: Uart host read failed:%d", __func__, ret);
42 OsalMemFree(buf);
43 return HDF_ERR_IO;
44 }
45
46 if (!HdfSbufWriteBuffer(reply, (ret == 0) ? NULL : buf, ret)) {
47 HDF_LOGE("%s: sbuf write buffer failed", __func__);
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("%s: sbuf read buffer failed", __func__);
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 return ret;
76 }
77 if (!HdfSbufWriteUint32(reply, baudRate)) {
78 HDF_LOGE("%s: sbuf write buffer failed", __func__);
79 return HDF_ERR_IO;
80 }
81 return HDF_SUCCESS;
82 }
83
UartIoSetBaud(struct UartHost * host,struct HdfSBuf * data)84 static int32_t UartIoSetBaud(struct UartHost *host, struct HdfSBuf *data)
85 {
86 uint32_t baudRate;
87
88 if (!HdfSbufReadUint32(data, &baudRate)) {
89 HDF_LOGE("%s: sbuf read buffer failed", __func__);
90 return HDF_ERR_IO;
91 }
92 return UartHostSetBaud(host, baudRate);
93 }
94
UartIoGetAttribute(struct UartHost * host,struct HdfSBuf * reply)95 static int32_t UartIoGetAttribute(struct UartHost *host, struct HdfSBuf *reply)
96 {
97 int32_t ret;
98 struct UartAttribute attribute;
99
100 ret = UartHostGetAttribute(host, &attribute);
101 if (ret != HDF_SUCCESS) {
102 return ret;
103 }
104 if (!HdfSbufWriteBuffer(reply, &attribute, sizeof(attribute))) {
105 HDF_LOGE("%s: sbuf write buffer failed", __func__);
106 return HDF_ERR_IO;
107 }
108 return HDF_SUCCESS;
109 }
110
UartIoSetAttribute(struct UartHost * host,struct HdfSBuf * data)111 static int32_t UartIoSetAttribute(struct UartHost *host, struct HdfSBuf *data)
112 {
113 uint32_t size;
114 struct UartAttribute *attribute = NULL;
115
116 if (!HdfSbufReadBuffer(data, (const void **)&attribute, &size)) {
117 HDF_LOGE("%s: sbuf read buffer failed", __func__);
118 return HDF_ERR_IO;
119 }
120
121 if (size != sizeof(*attribute)) {
122 HDF_LOGE("%s: sbuf read size not match, exp:%zu, got:%u", __func__, sizeof(*attribute), size);
123 return HDF_ERR_IO;
124 }
125
126 return UartHostSetAttribute(host, attribute);
127 }
128
UartIoSetTransMode(struct UartHost * host,struct HdfSBuf * data)129 static int32_t UartIoSetTransMode(struct UartHost *host, struct HdfSBuf *data)
130 {
131 uint32_t mode;
132
133 if (!HdfSbufReadUint32(data, &mode)) {
134 HDF_LOGE("%s: sbuf read mode failed", __func__);
135 return HDF_ERR_IO;
136 }
137 return UartHostSetTransMode(host, mode);
138 }
139
UartIoDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)140 int32_t UartIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
141 {
142 struct UartHost *host = NULL;
143
144 if (client == NULL) {
145 HDF_LOGE("%s: client is NULL", __func__);
146 return HDF_ERR_INVALID_OBJECT;
147 }
148
149 if (client->device == NULL) {
150 HDF_LOGE("%s: client->device is NULL", __func__);
151 return HDF_ERR_INVALID_OBJECT;
152 }
153
154 if (client->device->service == NULL) {
155 HDF_LOGE("%s: client->device->service is NULL", __func__);
156 return HDF_ERR_INVALID_OBJECT;
157 }
158
159 host = (struct UartHost *)client->device->service;
160 switch (cmd) {
161 case UART_IO_REQUEST:
162 return UartHostRequest(host);
163 case UART_IO_RELEASE:
164 return UartHostRelease(host);
165 case UART_IO_READ:
166 return UartIoRead(host, data, reply);
167 case UART_IO_WRITE:
168 return UartIoWrite(host, data);
169 case UART_IO_GET_BAUD:
170 return UartIoGetBaud(host, reply);
171 case UART_IO_SET_BAUD:
172 return UartIoSetBaud(host, data);
173 case UART_IO_GET_ATTRIBUTE:
174 return UartIoGetAttribute(host, reply);
175 case UART_IO_SET_ATTRIBUTE:
176 return UartIoSetAttribute(host, data);
177 case UART_IO_SET_TRANSMODE:
178 return UartIoSetTransMode(host, data);
179 default:
180 return HDF_ERR_NOT_SUPPORT;
181 }
182 }
183