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 33enum 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 USB_SERIAL_READ_SPEED, 48 USB_SERIAL_READ_GET_TEMP_SPEED, 49 USB_SERIAL_READ_SPEED_DONE, 50 USB_SERIAL_READ_GET_TEMP_SPEED_UINT32, 51}; 52 53static struct HdfSBuf *g_data; 54static struct HdfSBuf *g_reply; 55static struct HdfIoService *g_acmService; 56static bool g_readRuning = false; 57static sigset_t g_mask; 58static void TestSpeed(void) 59{ 60 HdfSbufFlush(g_reply); 61 int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_READ_SPEED, g_data, g_reply); 62 if (status != HDF_SUCCESS) { 63 HDF_LOGE("%{public}s: Dispatch USB_SERIAL_READ_SPEED err", __func__); 64 return; 65 } 66} 67 68static void GetTempSpeed(void) 69{ 70 const float calc = 10000; 71 uint32_t speed = 0; 72 HdfSbufFlush(g_reply); 73 int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, 74 USB_SERIAL_READ_GET_TEMP_SPEED_UINT32, g_data, g_reply); 75 if (status != HDF_SUCCESS) { 76 HDF_LOGE("%{public}s: Dispatch USB_SERIAL_WRITE_GET_TEMP_SPEED failed status = %{public}d", 77 __func__, status); 78 return; 79 } 80 if (!HdfSbufReadUint32(g_reply, &speed)) { 81 HDF_LOGE("%{public}s: HdfSbufReadFloat failed", __func__); 82 return; 83 } 84 if (speed > 0) { 85 printf("speed : %f MB/s\n", (float)speed / calc); 86 } 87} 88 89static void ReadSpeedDone(void) 90{ 91 int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, 92 USB_SERIAL_READ_SPEED_DONE, g_data, g_reply); 93 if (status != HDF_SUCCESS) { 94 HDF_LOGE("%{public}s: Dispatch USB_SERIAL_WRITE_SPEED_DONE failed status = %{public}d", 95 __func__, status); 96 return; 97 } 98} 99 100static void *StopHandler(void *arg) 101{ 102 (void)arg; 103 int32_t signo; 104 while (1) { 105 int32_t err = sigwait(&g_mask, &signo); 106 if (err != 0) { 107 printf("Sigwait failed: %d\n", err); 108 } 109 110 switch (signo) { 111 case SIGINT: 112 case SIGQUIT: 113 printf("AcmSpeedRead exit\n"); 114 ReadSpeedDone(); 115 g_readRuning = false; 116 return NULL; 117 default: 118 printf("Unexpected signal %d\n", signo); 119 } 120 } 121} 122 123static pthread_t g_threads; 124static void StartStopHandler(void) 125{ 126 sigemptyset(&g_mask); 127 sigaddset(&g_mask, SIGINT); 128 sigaddset(&g_mask, SIGQUIT); 129 if (pthread_sigmask(SIG_BLOCK, &g_mask, NULL) != 0) { 130 printf("SIG_BLOCK error\n"); 131 return; 132 } 133 if (pthread_create(&g_threads, NULL, StopHandler, NULL) != 0) { 134 printf("Could not create core thread\n"); 135 return; 136 } 137} 138 139int32_t AcmSpeedRead(int32_t argc, const char *argv[]) 140{ 141 (void)argc; 142 (void)argv; 143 int32_t status; 144 g_acmService = HdfIoServiceBind("usbfn_cdcacm"); 145 if (g_acmService == NULL || g_acmService->dispatcher == NULL || g_acmService->dispatcher->Dispatch == NULL) { 146 HDF_LOGE("%{public}s: GetService err", __func__); 147 return HDF_FAILURE; 148 } 149 150 g_data = HdfSbufObtainDefaultSize(); 151 g_reply = HdfSbufObtainDefaultSize(); 152 if (g_data == NULL || g_reply == NULL) { 153 HDF_LOGE("%{public}s: GetService err", __func__); 154 return HDF_FAILURE; 155 } 156 157 status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_OPEN, g_data, g_reply); 158 if (status != HDF_SUCCESS) { 159 HDF_LOGE("%{public}s: Dispatch USB_SERIAL_OPEN err", __func__); 160 return HDF_FAILURE; 161 } 162 163 StartStopHandler(); 164 TestSpeed(); 165 g_readRuning = true; 166 while (g_readRuning) { 167 sleep(0x2); 168 if (g_readRuning) { 169 GetTempSpeed(); 170 } 171 } 172 173 HdfSbufRecycle(g_data); 174 HdfSbufRecycle(g_reply); 175 HdfIoServiceRecycle(g_acmService); 176 return 0; 177} 178