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 "uart_test.h"
10 #include "hdf_base.h"
11 #include "hdf_io_service_if.h"
12 #include "hdf_log.h"
13 #include "osal_mem.h"
14 #include "osal_time.h"
15 #include "securec.h"
16 #include "uart_if.h"
17 
18 #define HDF_LOG_TAG uart_test
19 
UartTestGetConfig(struct UartTestConfig * config)20 static int32_t UartTestGetConfig(struct UartTestConfig *config)
21 {
22     int32_t ret;
23     struct HdfSBuf *reply = NULL;
24     struct HdfIoService *service = NULL;
25     const void *buf = NULL;
26     uint32_t len;
27 
28     service = HdfIoServiceBind("UART_TEST");
29     if (service == NULL) {
30         HDF_LOGE("UartTestGetConfig: fail to bind service!");
31         return HDF_ERR_NOT_SUPPORT;
32     }
33 
34     do {
35         reply = HdfSbufObtainDefaultSize();
36         if (reply == NULL) {
37             HDF_LOGE("UartTestGetConfig: fail to obtain reply!");
38             ret = HDF_ERR_MALLOC_FAIL;
39             break;
40         }
41 
42         ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
43         if (ret != HDF_SUCCESS) {
44             HDF_LOGE("UartTestGetConfig: remote dispatch fail, ret: %d!", ret);
45             break;
46         }
47 
48         if (!HdfSbufReadUint32(reply, &config->port)) {
49             HDF_LOGE("UartTestGetConfig: read port fail!");
50             ret = HDF_ERR_IO;
51             break;
52         }
53         if (!HdfSbufReadUint32(reply, &config->len)) {
54             HDF_LOGE("UartTestGetConfig: read len fail!");
55             ret = HDF_ERR_IO;
56             break;
57         }
58 
59         if (!HdfSbufReadBuffer(reply, (const void **)&buf, &len)) {
60             HDF_LOGE("UartTestGetConfig: read buf fail!");
61             ret = HDF_ERR_IO;
62             break;
63         }
64 
65         if (len != config->len) {
66             HDF_LOGE("UartTestGetConfig: config len:%u, read size:%u!", config->len, len);
67             ret = HDF_ERR_IO;
68             break;
69         }
70         config->wbuf = NULL;
71         config->wbuf = (uint8_t *)OsalMemCalloc(len);
72         if (config->wbuf == NULL) {
73             HDF_LOGE("UartTestGetConfig: malloc wbuf fail!");
74             ret = HDF_ERR_MALLOC_FAIL;
75             break;
76         }
77         config->rbuf = NULL;
78         config->rbuf = (uint8_t *)OsalMemCalloc(len);
79         if (config->rbuf == NULL) {
80             HDF_LOGE("UartTestGetConfig: malloc rbuf fail!");
81             ret = HDF_ERR_MALLOC_FAIL;
82             break;
83         }
84 
85         if (memcpy_s(config->wbuf, config->len, buf, len) != EOK) {
86             HDF_LOGE("UartTestGetConfig: Memcpy wbuf fail!");
87             ret = HDF_ERR_IO;
88             break;
89         }
90 
91         HDF_LOGD("UartTestGetConfig: done!");
92         ret = HDF_SUCCESS;
93     } while (0);
94     HdfSbufRecycle(reply);
95     HdfIoServiceRecycle(service);
96     return ret;
97 }
98 
UartBufFree(struct UartTestConfig * config)99 static inline void UartBufFree(struct UartTestConfig *config)
100 {
101     OsalMemFree(config->wbuf);
102     config->wbuf = NULL;
103     OsalMemFree(config->rbuf);
104     config->rbuf = NULL;
105 }
106 
UartTesterGet(void)107 static struct UartTester *UartTesterGet(void)
108 {
109     int32_t ret;
110     static struct UartTester tester;
111 
112     ret = UartTestGetConfig(&tester.config);
113     if (ret != HDF_SUCCESS) {
114         HDF_LOGE("UartTesterGet: read config fail, ret: %d!", ret);
115         UartBufFree(&tester.config);
116         return NULL;
117     }
118     tester.handle = UartOpen(tester.config.port);
119     if (tester.handle == NULL) {
120         HDF_LOGE("UartTesterGet: open uart port:%u fail!", tester.config.port);
121         UartBufFree(&tester.config);
122         return NULL;
123     }
124     return &tester;
125 }
126 
UartTesterPut(struct UartTester * tester)127 static void UartTesterPut(struct UartTester *tester)
128 {
129     if (tester == NULL || tester->handle == NULL) {
130         HDF_LOGE("UartTesterPut: tester or uart handle is null!");
131         return;
132     }
133     UartBufFree(&tester->config);
134     UartClose(tester->handle);
135     tester->handle = NULL;
136 }
137 
UartWriteTest(struct UartTester * tester)138 static int32_t UartWriteTest(struct UartTester *tester)
139 {
140     int32_t ret;
141 
142     ret = UartWrite(tester->handle, tester->config.wbuf, tester->config.len);
143     HDF_LOGD("UartWriteTest: len is %d", tester->config.len);
144     if (ret != HDF_SUCCESS) {
145         HDF_LOGE("UartWriteTest: write fail!");
146         return HDF_FAILURE;
147     }
148     HDF_LOGD("UartWriteTest: success!");
149     return HDF_SUCCESS;
150 }
151 
UartReadTest(struct UartTester * tester)152 static int32_t UartReadTest(struct UartTester *tester)
153 {
154     int32_t ret;
155 
156     ret = UartSetTransMode(tester->handle, UART_MODE_RD_NONBLOCK);
157     if (ret != HDF_SUCCESS) {
158         HDF_LOGE("UartReadTest: transmode error, ret: %d!", ret);
159         return ret;
160     }
161     ret = UartRead(tester->handle, tester->config.rbuf, tester->config.len);
162     if (ret != HDF_SUCCESS) {
163         HDF_LOGE("UartReadTest: read fail, ret: %d!", ret);
164         return ret;
165     }
166     HDF_LOGD("UartReadTest: success!");
167     return HDF_SUCCESS;
168 }
169 
170 #define BAUD_921600 921600
UartSetBaudTest(struct UartTester * tester)171 static int32_t UartSetBaudTest(struct UartTester *tester)
172 {
173     int32_t ret;
174 
175     ret = UartSetBaud(tester->handle, BAUD_921600);
176     if (ret != HDF_SUCCESS) {
177         HDF_LOGE("UartSetBaudTest: set baud fail, ret: %d!", ret);
178         return ret;
179     }
180     HDF_LOGD("UartSetBaudTest: success!");
181     return HDF_SUCCESS;
182 }
183 
UartGetBaudTest(struct UartTester * tester)184 static int32_t UartGetBaudTest(struct UartTester *tester)
185 {
186     int32_t ret;
187     uint32_t baud;
188 
189     ret = UartGetBaud(tester->handle, &baud);
190     if (ret != HDF_SUCCESS) {
191         HDF_LOGE("UartGetBaudTest: get baud fail, ret: %d!", ret);
192         return ret;
193     }
194     HDF_LOGD("UartGetBaudTest: baud %u success!", baud);
195     return HDF_SUCCESS;
196 }
197 
UartSetAttributeTest(struct UartTester * tester)198 static int32_t UartSetAttributeTest(struct UartTester *tester)
199 {
200     struct UartAttribute attribute;
201     int32_t ret;
202 
203     attribute.dataBits = UART_ATTR_DATABIT_7;
204     attribute.parity = UART_ATTR_PARITY_NONE;
205     attribute.stopBits = UART_ATTR_STOPBIT_1;
206     attribute.rts = UART_ATTR_RTS_DIS;
207     attribute.cts = UART_ATTR_CTS_DIS;
208     attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN;
209     attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN;
210     ret = UartSetAttribute(tester->handle, &attribute);
211     if (ret != HDF_SUCCESS) {
212         HDF_LOGE("UartSetAttributeTest: set attribute fail, ret: %d!", ret);
213         return ret;
214     }
215     HDF_LOGD("UartSetAttributeTest: success!");
216     return HDF_SUCCESS;
217 }
218 
UartGetAttributeTest(struct UartTester * tester)219 static int32_t UartGetAttributeTest(struct UartTester *tester)
220 {
221     struct UartAttribute attribute;
222     int32_t ret;
223 
224     ret = UartGetAttribute(tester->handle, &attribute);
225     if (ret != HDF_SUCCESS) {
226         HDF_LOGE("UartGetAttributeTest: get attribute fail, ret: %d!", ret);
227         return ret;
228     }
229     HDF_LOGD("UartGetAttributeTest: dataBits %u", attribute.dataBits);
230     HDF_LOGD("UartGetAttributeTest: parity %u", attribute.parity);
231     HDF_LOGD("UartGetAttributeTest: stopBits %u", attribute.stopBits);
232     HDF_LOGD("UartGetAttributeTest: rts %u", attribute.rts);
233     HDF_LOGD("UartGetAttributeTest: cts %u", attribute.cts);
234     HDF_LOGD("UartGetAttributeTest: fifoRxEn %u", attribute.fifoRxEn);
235     HDF_LOGD("UartGetAttributeTest: fifoTxEn %u", attribute.fifoTxEn);
236     HDF_LOGD("UartGetAttributeTest: success!");
237     return HDF_SUCCESS;
238 }
239 
UartSetTransModeTest(struct UartTester * tester)240 static int32_t UartSetTransModeTest(struct UartTester *tester)
241 {
242     int32_t ret;
243 
244     ret = UartSetTransMode(tester->handle, UART_MODE_RD_NONBLOCK);
245     if (ret != HDF_SUCCESS) {
246         HDF_LOGE("UartSetTransModeTest: set transmode fail, ret: %d!", ret);
247         return ret;
248     }
249     HDF_LOGD("UartSetTransModeTest: success!");
250     return HDF_SUCCESS;
251 }
252 
UartReliabilityTest(struct UartTester * tester)253 static int32_t UartReliabilityTest(struct UartTester *tester)
254 {
255     uint32_t baud;
256     struct UartAttribute attribute = {0};
257 
258     (void)UartSetTransMode(tester->handle, UART_MODE_RD_NONBLOCK);
259     (void)UartSetTransMode(tester->handle, -1);
260     (void)UartWrite(tester->handle, tester->config.wbuf, tester->config.len);
261     (void)UartWrite(tester->handle, NULL, -1);
262     (void)UartRead(tester->handle, tester->config.rbuf, tester->config.len);
263     (void)UartRead(tester->handle, NULL, -1);
264     (void)UartSetBaud(tester->handle, BAUD_921600);
265     (void)UartSetBaud(tester->handle, -1);
266     (void)UartGetBaud(tester->handle, &baud);
267     (void)UartGetBaud(tester->handle, NULL);
268     (void)UartSetAttribute(tester->handle, &attribute);
269     (void)UartSetAttribute(tester->handle, NULL);
270     (void)UartGetAttribute(tester->handle, &attribute);
271     (void)UartGetAttribute(tester->handle, NULL);
272     HDF_LOGD("UartReliabilityTest: success!");
273     return HDF_SUCCESS;
274 }
275 
UartIfPerformanceTest(struct UartTester * tester)276 static int32_t UartIfPerformanceTest(struct UartTester *tester)
277 {
278 #ifdef __LITEOS__
279     if (tester == NULL) {
280         HDF_LOGE("UartIfPerformanceTest: tester is null!");
281         return HDF_FAILURE;
282     }
283     return HDF_SUCCESS;
284 #endif
285     uint32_t baudRate;
286     uint64_t startMs;
287     uint64_t endMs;
288     uint64_t useTime;    // ms
289 
290     if (tester == NULL) {
291         HDF_LOGE("UartIfPerformanceTest: tester is null!");
292         return HDF_FAILURE;
293     }
294     startMs = OsalGetSysTimeMs();
295     UartGetBaud(tester->handle, &baudRate);
296     endMs = OsalGetSysTimeMs();
297 
298     useTime = endMs - startMs;
299     HDF_LOGI("UartIfPerformanceTest: ----->interface performance test:[start - end] < 1ms[%s]\r\n",
300         useTime < 1 ? "yes" : "no");
301     return HDF_SUCCESS;
302 }
303 
UartMiniBlockWriteTest(struct UartTester * tester)304 static int32_t UartMiniBlockWriteTest(struct UartTester *tester)
305 {
306 #ifdef __KERNEL__
307     uint8_t data;
308     int32_t ret;
309 
310     ret = UartBlockWrite(tester->handle, &data, sizeof(data));
311     if (ret != HDF_SUCCESS) {
312         HDF_LOGE("UartMiniBlockWriteTest: uart block write fail, ret: %d!", ret);
313         return ret;
314     }
315 #else
316     (void)tester;
317 #endif
318     HDF_LOGI("UartMiniBlockWriteTest: all test done!");
319     return HDF_SUCCESS;
320 }
321 
322 struct UartTestEntry {
323     int cmd;
324     int32_t (*func)(struct UartTester *tester);
325     const char *name;
326 };
327 
328 static struct UartTestEntry g_entry[] = {
329     { UART_TEST_CMD_WRITE, UartWriteTest, "UartWriteTest" },
330     { UART_TEST_CMD_READ, UartReadTest, "UartReadTest" },
331     { UART_TEST_CMD_SET_BAUD, UartSetBaudTest, "UartSetBaudTest" },
332     { UART_TEST_CMD_GET_BAUD, UartGetBaudTest, "UartGetBaudTest" },
333     { UART_TEST_CMD_SET_ATTRIBUTE, UartSetAttributeTest, "UartSetAttributeTest" },
334     { UART_TEST_CMD_GET_ATTRIBUTE, UartGetAttributeTest, "UartGetAttributeTest" },
335     { UART_TEST_CMD_SET_TRANSMODE, UartSetTransModeTest, "UartSetTransModeTest" },
336     { UART_TEST_CMD_RELIABILITY, UartReliabilityTest, "UartReliabilityTest" },
337     { UART_TEST_CMD_PERFORMANCE, UartIfPerformanceTest, "UartIfPerformanceTest" },
338     { UART_MINI_BLOCK_WRITE_TEST, UartMiniBlockWriteTest, "UartMiniBlockWriteTest" },
339 };
340 
UartTestExecute(int cmd)341 int32_t UartTestExecute(int cmd)
342 {
343     uint32_t i;
344     int32_t ret = HDF_ERR_NOT_SUPPORT;
345     struct UartTester *tester = NULL;
346 
347     tester = UartTesterGet();
348     if (tester == NULL) {
349         HDF_LOGE("UartTestExecute: tester is null!");
350         return HDF_ERR_INVALID_OBJECT;
351     }
352 
353     if (cmd > UART_TEST_CMD_MAX) {
354         HDF_LOGE("UartTestExecute: invalid cmd:%d!", cmd);
355         ret = HDF_ERR_NOT_SUPPORT;
356         HDF_LOGE("[UartTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
357         UartTesterPut(tester);
358         return ret;
359     }
360 
361     for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
362         if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
363             continue;
364         }
365         ret = g_entry[i].func(tester);
366         break;
367     }
368 
369     HDF_LOGE("[UartTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
370     UartTesterPut(tester);
371     return ret;
372 }
373