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 <pthread.h> 17#include <stdio.h> 18#include <sys/time.h> 19#include <unistd.h> 20 21#include "hdf_io_service_if.h" 22#include "hdf_log.h" 23#include "osal_mem.h" 24#include "osal_mutex.h" 25#include "osal_thread.h" 26#include "osal_time.h" 27#include "securec.h" 28#include "usb_dev_test.h" 29 30#define HDF_LOG_TAG cdc_acm_test 31 32enum UsbSerialCmd { 33 USB_SERIAL_OPEN = 0, 34 USB_SERIAL_CLOSE, 35 USB_SERIAL_READ, 36 USB_SERIAL_WRITE, 37 USB_SERIAL_GET_BAUDRATE, 38 USB_SERIAL_SET_BAUDRATE, 39 USB_SERIAL_SET_PROP, 40 USB_SERIAL_GET_PROP, 41 USB_SERIAL_REGIST_PROP, 42}; 43 44static struct HdfSBuf *g_data; 45static struct HdfSBuf *g_reply; 46static struct HdfIoService *g_acmService; 47static struct OsalMutex g_lock; 48 49static void TestWrite(const char *buf) 50{ 51 HdfSbufFlush(g_data); 52 (void)HdfSbufWriteString(g_data, buf); 53 int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_WRITE, g_data, g_reply); 54 if (status != HDF_SUCCESS) { 55 HDF_LOGE("%{public}s: Dispatch USB_SERIAL_WRITE failed status = %{public}d", __func__, status); 56 } 57} 58 59static void TestRead(void) 60{ 61 HdfSbufFlush(g_reply); 62 int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_READ, g_data, g_reply); 63 if (status != HDF_SUCCESS) { 64 printf("%s: Dispatch USB_SERIAL_READ failed status = %d", __func__, status); 65 return; 66 } 67 if (HdfSbufGetDataSize(g_reply) != 0) { 68 const char *tmp = HdfSbufReadString(g_reply); 69 if (tmp && strlen(tmp) > 0) { 70 printf("%s: read : %s \n", __func__, tmp); 71 } 72 } 73} 74 75static bool g_readRuning = false; 76#define SLEEP_READ 100 77static void ReadThread(void *arg) 78{ 79 (void)arg; 80 while (g_readRuning) { 81 OsalMutexLock(&g_lock); 82 TestRead(); 83 OsalMutexUnlock(&g_lock); 84 OsalMDelay(SLEEP_READ); 85 } 86} 87 88static void StartPThreadRead(void) 89{ 90 pthread_t tid; 91 if ((pthread_create(&tid, NULL, ReadThread, NULL)) == -1) { 92 printf("create error!\n"); 93 } 94} 95 96#define STR_LEN 256 97#define SLEEP_GETCHAR 100000 98static void Test02(void) 99{ 100 char str[STR_LEN] = {0}; 101 char *getStr = NULL; 102 if (OsalMutexInit(&g_lock) != HDF_SUCCESS) { 103 HDF_LOGE("%{public}s: init lock fail!", __func__); 104 return; 105 } 106 while (1) { 107 printf("\ninput: \nr: for read acm\nw: for write acm \nq: for exit \n"); 108 char ch = (char)getchar(); 109 if (ch == 'r') { 110 printf("input: 'q' quit reading\n"); 111 g_readRuning = true; 112 StartPThreadRead(); 113 while (getchar() != 'q') { 114 printf("input: 'q' quit reading\n"); 115 usleep(SLEEP_GETCHAR); 116 } 117 g_readRuning = false; 118 } else if (ch == 'w') { 119 printf("input strings and press enter to send\n"); 120 getchar(); 121 getStr = gets_s(str, STR_LEN - 1); 122 if (getStr == NULL) { 123 HDF_LOGE("%{public}s: gets_s failed", __func__); 124 } 125 TestWrite(str); 126 } else if (ch == 'q') { 127 return; 128 } 129 } 130} 131 132int32_t AcmTest(int32_t argc, const char *argv[]) 133{ 134 (void)argc; 135 (void)argv; 136 int32_t status; 137 g_acmService = HdfIoServiceBind("usbfn_cdcacm"); 138 if (g_acmService == NULL || g_acmService->dispatcher == NULL || g_acmService->dispatcher->Dispatch == NULL) { 139 HDF_LOGE("%{public}s: GetService err", __func__); 140 return HDF_FAILURE; 141 } 142 143 g_data = HdfSbufObtainDefaultSize(); 144 g_reply = HdfSbufObtainDefaultSize(); 145 if (g_data == NULL || g_reply == NULL) { 146 HDF_LOGE("%{public}s: GetService err", __func__); 147 return HDF_FAILURE; 148 } 149 150 status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_OPEN, g_data, g_reply); 151 if (status != HDF_SUCCESS) { 152 HDF_LOGE("%{public}s: Dispatch USB_SERIAL_OPEN err", __func__); 153 return HDF_FAILURE; 154 } 155 156 Test02(); 157 158 status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_CLOSE, g_data, g_reply); 159 if (status != HDF_SUCCESS) { 160 HDF_LOGE("%{public}s: Dispatch USB_SERIAL_CLOSE err", __func__); 161 return HDF_FAILURE; 162 } 163 164 HdfSbufRecycle(g_data); 165 HdfSbufRecycle(g_reply); 166 return HDF_SUCCESS; 167} 168