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_log.h>
17 #include <hdf_remote_service.h>
18 #include <hdf_sbuf.h>
19 #include <servmgr_hdi.h>
20 #include <unistd.h>
21 #include <sys/time.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <termios.h>
25 #include "cdcacm.h"
26 #include "osal_time.h"
27 #include <signal.h>
28
29 #define HDF_LOG_TAG cdc_acm_test
30
31 static int running = 1;
32 static struct termios g_orgOpts, g_newOpts;
33 static struct HdfSBuf *g_data;
34 static struct HdfSBuf *g_reply;
35 static struct HdfRemoteService *g_acmService;
36 static struct OsalThread g_thread;
37
TestWrite(char * buf)38 static void TestWrite(char *buf)
39 {
40 HdfSbufFlush(g_data);
41 (void)HdfSbufWriteString(g_data, buf);
42 int status = g_acmService->dispatcher->Dispatch(g_acmService, USB_SERIAL_WRITE, g_data, g_reply);
43 if (status <= 0) {
44 HDF_LOGE("%s: Dispatch USB_SERIAL_WRITE failed status = %d", __func__, status);
45 }
46 }
47
TestRead()48 static void TestRead()
49 {
50 size_t i;
51 HdfSbufFlush(g_reply);
52 int status = g_acmService->dispatcher->Dispatch(g_acmService, USB_SERIAL_READ, g_data, g_reply);
53 if (status) {
54 printf("%s: Dispatch USB_SERIAL_READ failed status = %d", __func__, status);
55 return;
56 }
57 const char *tmp = HdfSbufReadString(g_reply);
58 if (tmp && strlen(tmp) > 0) {
59 for (i = 0; i < strlen(tmp); i++) {
60 if (tmp[i] == 0x0A || tmp[i] == 0x0D) {
61 printf("\r\n");
62 } else {
63 putchar(tmp[i]);
64 }
65 }
66 fflush(stdout);
67 }
68 }
69
70 #define SLEEP_100MS 100000
ReadThread(void * arg)71 static int ReadThread(void *arg)
72 {
73 while (running) {
74 TestRead();
75 usleep(SLEEP_100MS);
76 }
77 return 0;
78 }
79 #define HDF_PROCESS_STACK_SIZE 10000
StartThreadRead()80 static int StartThreadRead()
81 {
82 int ret;
83 struct OsalThreadParam threadCfg;
84 memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
85 threadCfg.name = "Read process";
86 threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
87 threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
88
89 ret = OsalThreadCreate(&g_thread, (OsalThreadEntry)ReadThread, NULL);
90 if (HDF_SUCCESS != ret) {
91 HDF_LOGE("%s:%d OsalThreadCreate faile, ret=%d ", __func__, __LINE__, ret);
92 return HDF_ERR_DEVICE_BUSY;
93 }
94
95 ret = OsalThreadStart(&g_thread, &threadCfg);
96 if (HDF_SUCCESS != ret) {
97 HDF_LOGE("%s:%d OsalThreadStart faile, ret=%d ", __func__, __LINE__, ret);
98 return HDF_ERR_DEVICE_BUSY;
99 }
100 return 0;
101 }
102
SetTermios()103 static void SetTermios()
104 {
105 tcgetattr(STDIN_FILENO, &g_orgOpts);
106 tcgetattr(STDIN_FILENO, &g_newOpts);
107 g_newOpts.c_lflag &= ~(ICANON | ECHOE | ECHOK | ECHONL);
108 tcsetattr(STDIN_FILENO, TCSANOW, &g_newOpts);
109 }
110
111 #define STR_LEN 256
WriteThread()112 static void WriteThread()
113 {
114 char str[STR_LEN] = {0};
115 while (running) {
116 str[0] = getchar();
117 if (running) {
118 TestWrite(str);
119 }
120 }
121 }
122
StopAcmTest(int signo)123 void StopAcmTest(int signo)
124 {
125 int status;
126 running = 0;
127 status = g_acmService->dispatcher->Dispatch(g_acmService, USB_SERIAL_CLOSE, g_data, g_reply);
128 if (status) {
129 HDF_LOGE("%s: Dispatch USB_SERIAL_CLOSE err", __func__);
130 }
131 tcsetattr(STDIN_FILENO, TCSANOW, &g_orgOpts);
132 printf("acm_test exit.\n");
133 }
134
main(int argc,char * argv[])135 int main(int argc, char *argv[])
136 {
137 int status;
138 struct HDIServiceManager *servmgr = HDIServiceManagerGet();
139 if (servmgr == NULL) {
140 HDF_LOGE("%s: HDIServiceManagerGet err", __func__);
141 return HDF_FAILURE;
142 }
143 g_acmService = servmgr->GetService(servmgr, "usbfn_cdcacm");
144 HDIServiceManagerRelease(servmgr);
145 if (g_acmService == NULL) {
146 HDF_LOGE("%s: GetService err", __func__);
147 return HDF_FAILURE;
148 }
149
150 g_data = HdfSBufTypedObtain(SBUF_IPC);
151 g_reply = HdfSBufTypedObtain(SBUF_IPC);
152 if (g_data == NULL || g_reply == NULL) {
153 HDF_LOGE("%s: GetService err", __func__);
154 return HDF_FAILURE;
155 }
156
157 status = g_acmService->dispatcher->Dispatch(g_acmService, USB_SERIAL_OPEN, g_data, g_reply);
158 if (status) {
159 HDF_LOGE("%s: Dispatch USB_SERIAL_OPEN err", __func__);
160 return HDF_FAILURE;
161 }
162 printf("Press any key to send.\n");
163 printf("Press CTRL-C to exit.\n");
164
165 signal(SIGINT, StopAcmTest);
166 StartThreadRead();
167 SetTermios();
168 WriteThread();
169 return 0;
170 }
171