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