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 <fcntl.h>
17 #include <hdf_io_service_if.h>
18 #include <hdf_log.h>
19 #include <osal_file.h>
20 #include <osal_mem.h>
21 #include <osal_mutex.h>
22 #include <osal_thread.h>
23 #include <osal_time.h>
24 #include <pthread.h>
25 #include <securec.h>
26 #include <signal.h>
27 #include <stdio.h>
28 #include <sys/time.h>
29 #include <unistd.h>
30
31 #define HDF_LOG_TAG cdc_acm_speed
32
33 enum UsbSerialCmd {
34 USB_SERIAL_OPEN = 0,
35 USB_SERIAL_CLOSE,
36 USB_SERIAL_READ,
37 USB_SERIAL_WRITE,
38 USB_SERIAL_GET_BAUDRATE,
39 USB_SERIAL_SET_BAUDRATE,
40 USB_SERIAL_SET_PROP,
41 USB_SERIAL_GET_PROP,
42 USB_SERIAL_REGIST_PROP,
43 USB_SERIAL_WRITE_SPEED,
44 USB_SERIAL_WRITE_GET_TEMP_SPEED,
45 USB_SERIAL_WRITE_SPEED_DONE,
46 USB_SERIAL_WRITE_GET_TEMP_SPEED_UINT32,
47 };
48
49 static struct HdfSBuf *g_data;
50 static struct HdfSBuf *g_reply;
51 static struct HdfIoService *g_acmService;
52 static bool g_readRuning = false;
53 static sigset_t g_mask;
54
TestSpeed(void)55 static void TestSpeed(void)
56 {
57 HdfSbufFlush(g_reply);
58 int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object,
59 USB_SERIAL_WRITE_SPEED, g_data, g_reply);
60 if (status) {
61 HDF_LOGE("%s: Dispatch USB_SERIAL_WRITE_SPEED failed status = %d",
62 __func__, status);
63 return;
64 }
65 }
66
GetTempSpeed(void)67 static void GetTempSpeed(void)
68 {
69 const float calc = 10000;
70 uint32_t speed = 0;
71 HdfSbufFlush(g_reply);
72 int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object,
73 USB_SERIAL_WRITE_GET_TEMP_SPEED_UINT32, g_data, g_reply);
74 if (status) {
75 HDF_LOGE("%s: Dispatch USB_SERIAL_WRITE_GET_TEMP_SPEED failed status = %d",
76 __func__, status);
77 return;
78 }
79 if (!HdfSbufReadUint32(g_reply, &speed)) {
80 HDF_LOGE("%s: HdfSbufReadFloat failed", __func__);
81 return;
82 }
83 if (speed > 0) {
84 printf("speed : %f MB/s\n", (float)speed / calc);
85 }
86 }
87
WriteSpeedDone(void)88 static void WriteSpeedDone(void)
89 {
90 int32_t status = g_acmService->dispatcher->Dispatch(g_acmService,
91 USB_SERIAL_WRITE_SPEED_DONE, g_data, g_reply);
92 if (status) {
93 HDF_LOGE("%s: Dispatch USB_SERIAL_WRITE_SPEED_DONE failed status = %d",
94 __func__, status);
95 return;
96 }
97 }
98
StopHandler(void * arg)99 static void *StopHandler(void *arg)
100 {
101 int32_t err, signo;
102 while (1) {
103 err = sigwait(&g_mask, &signo);
104 if (err != 0) {
105 printf("Sigwait failed: %d\n", err);
106 }
107
108 switch (signo) {
109 case SIGINT:
110 case SIGQUIT:
111 printf("acm_speed_write exit\n");
112 WriteSpeedDone();
113 g_readRuning = false;
114 return NULL;
115 default:
116 printf("Unexpected signal %d\n", signo);
117 }
118 }
119 }
120
121 static pthread_t g_threads;
StartStopHandler(void)122 static void StartStopHandler(void)
123 {
124 sigemptyset(&g_mask);
125 sigaddset(&g_mask, SIGINT);
126 sigaddset(&g_mask, SIGQUIT);
127 if ((pthread_sigmask(SIG_BLOCK, &g_mask, NULL)) != 0) {
128 printf("SIG_BLOCK error\n");
129 return;
130 }
131 if (pthread_create(&g_threads, NULL, StopHandler, NULL) != 0) {
132 printf("Could not create core thread\n");
133 return;
134 }
135 }
136
acm_speed_write(int32_t argc,const char * argv[])137 int32_t acm_speed_write(int32_t argc, const char *argv[])
138 {
139 int32_t status;
140
141 g_acmService = HdfIoServiceBind("usbfn_cdcacm");
142 if (g_acmService == NULL || g_acmService->dispatcher == NULL || g_acmService->dispatcher->Dispatch == NULL) {
143 HDF_LOGE("%s: GetService err", __func__);
144 return HDF_FAILURE;
145 }
146
147 g_data = HdfSbufObtainDefaultSize();
148 g_reply = HdfSbufObtainDefaultSize();
149 if (g_data == NULL || g_reply == NULL) {
150 HDF_LOGE("%s: GetService err", __func__);
151 return HDF_FAILURE;
152 }
153
154 status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_OPEN, g_data, g_reply);
155 if (status) {
156 HDF_LOGE("%s: Dispatch USB_SERIAL_OPEN err", __func__);
157 return HDF_FAILURE;
158 }
159 StartStopHandler();
160 TestSpeed();
161 g_readRuning = true;
162 while (g_readRuning) {
163 sleep(0x2);
164 if (g_readRuning) {
165 GetTempSpeed();
166 }
167 }
168
169 status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_CLOSE, g_data, g_reply);
170 if (status) {
171 HDF_LOGE("%s: Dispatch USB_SERIAL_CLOSE err", __func__);
172 return HDF_FAILURE;
173 }
174
175 HdfSbufRecycle(g_data);
176 HdfSbufRecycle(g_reply);
177 HdfIoServiceRecycle(g_acmService);
178 return 0;
179 }
180