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 "osal_mem.h"
18 #include "hdf_io_service_if.h"
19 #include <unistd.h>
20 #include <sys/time.h>
21 #include <stdio.h>
22 #include "osal_thread.h"
23 #include "osal_mutex.h"
24 #include "osal_time.h"
25 #include "securec.h"
26 
27 #define HDF_LOG_TAG   cdc_acm_write
28 
29 enum UsbSerialCmd {
30     USB_SERIAL_OPEN = 0,
31     USB_SERIAL_CLOSE,
32     USB_SERIAL_READ,
33     USB_SERIAL_WRITE,
34     USB_SERIAL_GET_BAUDRATE,
35     USB_SERIAL_SET_BAUDRATE,
36     USB_SERIAL_SET_PROP,
37     USB_SERIAL_GET_PROP,
38     USB_SERIAL_REGIST_PROP,
39 };
40 struct HdfSBuf *g_data;
41 struct HdfSBuf *g_reply;
42 struct HdfIoService *g_acmService;
43 
check_service()44 static int32_t check_service()
45 {
46     if (g_acmService == NULL || g_acmService->dispatcher == NULL || g_acmService->dispatcher->Dispatch == NULL) {
47         HDF_LOGE("%{public}s: GetService err", __func__);
48         return HDF_FAILURE;
49     }
50     if (g_data == NULL || g_reply == NULL) {
51         HDF_LOGE("%{public}s: GetService err", __func__);
52         return HDF_FAILURE;
53     }
54     return HDF_SUCCESS;
55 }
56 
AcmOpen(void)57 void AcmOpen(void)
58 {
59     int32_t status;
60     g_acmService = HdfIoServiceBind("usbfn_cdcacm");
61     if (g_acmService == NULL || g_acmService->dispatcher == NULL || g_acmService->dispatcher->Dispatch == NULL) {
62         HDF_LOGE("%{public}s: GetService err", __func__);
63         return;
64     }
65     g_data = HdfSbufObtainDefaultSize();
66     g_reply = HdfSbufObtainDefaultSize();
67     if (g_data == NULL || g_reply == NULL) {
68         HDF_LOGE("%{public}s: GetService err", __func__);
69     }
70     status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_OPEN, g_data, g_reply);
71     if (status != HDF_SUCCESS) {
72         HDF_LOGE("%{public}s: Dispatch USB_SERIAL_OPEN err", __func__);
73     }
74 }
75 
AcmClose(void)76 void AcmClose(void)
77 {
78     int32_t status;
79     if (check_service()) {
80         HDF_LOGE("%{public}s: GetService err", __func__);
81         return;
82     }
83     status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_CLOSE, g_data, g_reply);
84     if (status != HDF_SUCCESS) {
85         HDF_LOGE("%{public}s: Dispatch USB_SERIAL_CLOSE err", __func__);
86     }
87     HdfSbufRecycle(g_data);
88     HdfSbufRecycle(g_reply);
89     HdfIoServiceRecycle(g_acmService);
90 }
91 
AcmWrite(const char * buf)92 void AcmWrite(const char *buf)
93 {
94     if (check_service()) {
95         HDF_LOGE("%{public}s: GetService err", __func__);
96         return;
97     }
98     HdfSbufFlush(g_data);
99     (void)HdfSbufWriteString(g_data, buf);
100     int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_WRITE, g_data, g_reply);
101     if (status != HDF_SUCCESS) {
102         HDF_LOGE("%{public}s: Dispatch USB_SERIAL_WRITE failed status = %{public}d", __func__, status);
103         return;
104     }
105     printf("AcmWrite:%s\n", buf);
106 }
107 
AcmRead(char * const str,int32_t timeout)108 void AcmRead(char * const str, int32_t timeout)
109 {
110     int32_t ret;
111     uint32_t maxLen = 256;
112     if (check_service()) {
113         HDF_LOGE("%{public}s: GetService err", __func__);
114         return;
115     }
116     while (timeout-- > 0) {
117         HdfSbufFlush(g_reply);
118         int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_READ, g_data, g_reply);
119         if (status != HDF_SUCCESS) {
120             HDF_LOGE("%{public}s: Dispatch USB_SERIAL_READ failed status = %{public}d", __func__, status);
121             return;
122         }
123         const char *tmp = HdfSbufReadString(g_reply);
124         if (str && tmp && strlen(tmp) > 0) {
125             ret = memcpy_s(str, maxLen, tmp, strlen(tmp));
126             if (ret != EOK) {
127                 HDF_LOGE("%{public}s:%{public}d ret=%{public}d memcpy_s error", __func__, __LINE__, ret);
128             }
129             printf("AcmRead:%s\n", tmp);
130             return;
131         }
132         sleep(1);
133     }
134 }
135 
acm_prop_regist(const char * propName,const char * propValue)136 void acm_prop_regist(const char *propName, const char *propValue)
137 {
138     if (check_service()) {
139         HDF_LOGE("%{public}s: GetService err", __func__);
140         return;
141     }
142     HdfSbufFlush(g_data);
143     (void)HdfSbufWriteString(g_data, propName);
144     (void)HdfSbufWriteString(g_data, propValue);
145     int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_REGIST_PROP, g_data, g_reply);
146     if (status != HDF_SUCCESS) {
147         HDF_LOGE("%{public}s: Dispatch USB_SERIAL_WRITE failed status = %{public}d", __func__, status);
148         return;
149     }
150     printf("prop_regist:%s = %s\n", propName, propValue);
151 }
152 
acm_prop_write(const char * propName,const char * propValue)153 void acm_prop_write(const char *propName, const char *propValue)
154 {
155     if (check_service()) {
156         HDF_LOGE("%{public}s: GetService err", __func__);
157         return;
158     }
159     HdfSbufFlush(g_data);
160     HdfSbufFlush(g_reply);
161     (void)HdfSbufWriteString(g_data, propName);
162     (void)HdfSbufWriteString(g_data, propValue);
163     if (g_acmService == NULL || g_acmService->dispatcher == NULL || g_acmService->dispatcher->Dispatch == NULL) {
164         HDF_LOGE("%{public}s: GetService err", __func__);
165         return;
166     }
167     int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_SET_PROP, g_data, g_reply);
168     if (status != HDF_SUCCESS) {
169         HDF_LOGE("%{public}s: Dispatch USB_SERIAL_WRITE failed status = %{public}d", __func__, status);
170         return;
171     }
172     printf("prop_write:%s = %s\n", propName, propValue);
173 }
174 
acm_prop_read(const char * propName,char * propValue)175 void acm_prop_read(const char *propName, char *propValue)
176 {
177     if (check_service()) {
178         HDF_LOGE("%{public}s: GetService err", __func__);
179         return;
180     }
181     HdfSbufFlush(g_data);
182     HdfSbufFlush(g_reply);
183     (void)HdfSbufWriteString(g_data, propName);
184     int32_t status = g_acmService->dispatcher->Dispatch(&g_acmService->object, USB_SERIAL_GET_PROP, g_data, g_reply);
185     if (status != HDF_SUCCESS) {
186         HDF_LOGE("%{public}s:%{public}d Dispatch USB_SERIAL_GET_PROP failed status = %{public}d",
187             __func__, __LINE__, status);
188         return;
189     }
190     const char *tmp = HdfSbufReadString(g_reply);
191     if (propValue && tmp && strlen(tmp) > 0) {
192         uint32_t maxLen = 256;
193         errno_t err = memcpy_s(propValue, maxLen, tmp, strlen(tmp));
194         if (err != EOK) {
195             HDF_LOGE("%{public}s:%{public}d err=%{public}d memcpy_s error", __func__, __LINE__, err);
196         }
197         printf("prop_read:%s\n", tmp);
198         return;
199     }
200 }
201