1 /*
2 * Copyright (c) 2025 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 "usb_serial_ddk_service.h"
17
18 #include <cerrno>
19 #include <fcntl.h>
20 #include <hdf_base.h>
21 #include <hdf_log.h>
22 #include <iproxy_broker.h>
23 #include <cstdlib>
24 #include <cstring>
25 #include <sys/ioctl.h>
26 #include <termios.h>
27 #include <unistd.h>
28
29 #include "ddk_sysfs_dev_node.h"
30 #include "usb_ddk_permission.h"
31 #include "usbd_wrapper.h"
32 #ifdef __LITEOS__
33 #include "usb_serial_liteos_adapter.h"
34 #else
35 #include "usb_serial_linux_adapter.h"
36 #endif
37
38 #define HDF_LOG_TAG usb_serial_ddk_service
39 using namespace OHOS::HDI::Usb::Ddk;
40 namespace OHOS {
41 namespace HDI {
42 namespace Usb {
43 namespace UsbSerialDdk {
44 namespace V1_0 {
45
46 constexpr uint8_t THIRTY_TWO_BIT = 32;
47 constexpr size_t MAX_BUFFER_LENGTH = 4096;
48
GetBusNum(uint64_t devId)49 inline uint32_t GetBusNum(uint64_t devId)
50 {
51 return static_cast<uint32_t>(devId >> THIRTY_TWO_BIT);
52 }
53
GetDevNum(uint64_t devId)54 inline uint32_t GetDevNum(uint64_t devId)
55 {
56 return static_cast<uint32_t>(devId & 0xFFFFFFFF);
57 }
58
VerifyPermission(const std::string & permissionName)59 static bool VerifyPermission(const std::string &permissionName)
60 {
61 return DdkPermissionManager::VerifyPermission(permissionName);
62 }
63
64 static const std::string PERMISSION_NAME = "ohos.permission.ACCESS_DDK_USB_SERIAL";
UsbSerialDdkImplGetInstance(void)65 extern "C" IUsbSerialDdk *UsbSerialDdkImplGetInstance(void)
66 {
67 std::shared_ptr<UsbSerialOsAdapter> osAdapter;
68 #ifdef __LITEOS__
69 osAdapter = std::make_shared<LiteosUsbSerialOsAdapter>();
70 #else
71 osAdapter = std::make_shared<LinuxUsbSerialOsAdapter>();
72 #endif
73 return new (std::nothrow) UsbSerialDdkService(osAdapter);
74 }
75
Init()76 int32_t UsbSerialDdkService::Init()
77 {
78 HDF_LOGI("Usb serial ddk init.");
79 if (!VerifyPermission(PERMISSION_NAME)) {
80 HDF_LOGE("%{public}s: no permission", __func__);
81 return USB_SERIAL_DDK_NO_PERM;
82 }
83 return HDF_SUCCESS;
84 }
85
Release()86 int32_t UsbSerialDdkService::Release()
87 {
88 HDF_LOGI("Usb serial ddk exit.");
89 if (!VerifyPermission(PERMISSION_NAME)) {
90 HDF_LOGE("%{public}s: no permission", __func__);
91 return USB_SERIAL_DDK_NO_PERM;
92 }
93 return HDF_SUCCESS;
94 }
95
Open(uint64_t deviceId,uint64_t interfaceIndex,OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev)96 int32_t UsbSerialDdkService::Open(uint64_t deviceId, uint64_t interfaceIndex,
97 OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev)
98 {
99 HDF_LOGI("Usb serial ddk Open.");
100 if (!VerifyPermission(PERMISSION_NAME)) {
101 HDF_LOGE("%{public}s: no permission", __func__);
102 return USB_SERIAL_DDK_NO_PERM;
103 }
104
105 uint32_t busNum = GetBusNum(deviceId);
106 uint32_t devNum = GetDevNum(deviceId);
107 SysfsDevNode devNode(busNum, devNum, interfaceIndex, "ttyUSB");
108 std::string path;
109 int32_t ret = devNode.FindPath(path);
110 if (ret != HDF_SUCCESS) {
111 HDF_LOGE("Get devNodePath ret: %{public}d\n", ret);
112 return USB_SERIAL_DDK_DEVICE_NOT_FOUND;
113 }
114 int fd = open(path.c_str(), O_RDWR | O_NOCTTY | O_SYNC);
115 if (fd < 0) {
116 HDF_LOGE("error %{public}d opening devNodePath: %{public}s\n", errno, strerror(errno));
117 return USB_SERIAL_DDK_IO_ERROR;
118 }
119 dev.fd = static_cast<uint32_t>(fd);
120 return HDF_SUCCESS;
121 }
122
Close(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev)123 int32_t UsbSerialDdkService::Close(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev)
124 {
125 HDF_LOGI("Usb serial ddk Close.");
126 if (!VerifyPermission(PERMISSION_NAME)) {
127 HDF_LOGE("%{public}s: no permission", __func__);
128 return USB_SERIAL_DDK_NO_PERM;
129 }
130
131 int ret = close(static_cast<int32_t>(dev.fd));
132 if (ret != 0) {
133 HDF_LOGE("Failed to close device: %{public}s.\n", strerror(errno));
134 if (errno == EBADF) {
135 return USB_SERIAL_DDK_INVALID_OPERATION;
136 }
137 return USB_SERIAL_DDK_IO_ERROR;
138 }
139 return HDF_SUCCESS;
140 }
141
Read(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev,uint32_t bufferSize,std::vector<uint8_t> & buff)142 int32_t UsbSerialDdkService::Read(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev,
143 uint32_t bufferSize, std::vector<uint8_t> &buff)
144 {
145 HDF_LOGI("Usb serial ddk Read.");
146 if (!VerifyPermission(PERMISSION_NAME)) {
147 HDF_LOGE("%{public}s: no permission", __func__);
148 return USB_SERIAL_DDK_NO_PERM;
149 }
150
151 if (bufferSize == 0) {
152 HDF_LOGE("BufferSize error.\n");
153 return USB_SERIAL_DDK_INVALID_PARAMETER;
154 }
155 if (osAdapter_ == nullptr) {
156 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
157 return USB_SERIAL_DDK_INVALID_OPERATION;
158 }
159 uint32_t readBuffMaxSize = bufferSize;
160 if (readBuffMaxSize > MAX_BUFFER_LENGTH) {
161 readBuffMaxSize = MAX_BUFFER_LENGTH;
162 }
163 buff.resize(readBuffMaxSize);
164 ssize_t bytesRead = read(static_cast<int32_t>(dev.fd), &buff[0], readBuffMaxSize);
165 if (bytesRead < 0) {
166 HDF_LOGE("bytesRead error %{public}s.\n", strerror(errno));
167 if (errno == EBADF) {
168 return USB_SERIAL_DDK_INVALID_OPERATION;
169 } else {
170 return USB_SERIAL_DDK_IO_ERROR;
171 }
172 } else if (bytesRead == 0) {
173 bool ret = osAdapter_->IsDeviceDisconnect(static_cast<int32_t>(dev.fd));
174 if (ret) {
175 return USB_SERIAL_DDK_IO_ERROR;
176 }
177 return HDF_SUCCESS;
178 }
179 buff.resize(bytesRead);
180 return HDF_SUCCESS;
181 }
182
Write(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev,const std::vector<uint8_t> & buff,uint32_t & bytesWritten)183 int32_t UsbSerialDdkService::Write(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev,
184 const std::vector<uint8_t> &buff, uint32_t &bytesWritten)
185 {
186 HDF_LOGI("Usb serial ddk Write.");
187 if (!VerifyPermission(PERMISSION_NAME)) {
188 HDF_LOGE("%{public}s: no permission", __func__);
189 return USB_SERIAL_DDK_NO_PERM;
190 }
191
192 if (buff.empty()) {
193 HDF_LOGW("Buffer is empty. Nothing to write.");
194 bytesWritten = 0;
195 return HDF_SUCCESS;
196 }
197
198 ssize_t result = write(static_cast<int32_t>(dev.fd), buff.data(), buff.size());
199 if (result < 0) {
200 HDF_LOGE("Error writing to device: %{public}s", strerror(errno));
201 if (errno == EBADF) {
202 return USB_SERIAL_DDK_INVALID_OPERATION;
203 }
204 return USB_SERIAL_DDK_IO_ERROR;
205 } else {
206 bytesWritten = static_cast<uint32_t>(result);
207 HDF_LOGI("Successfully write %{public}u bytes.", bytesWritten);
208 }
209 return HDF_SUCCESS;
210 }
211
SetBaudRate(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev,uint32_t baudRate)212 int32_t UsbSerialDdkService::SetBaudRate(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev,
213 uint32_t baudRate)
214 {
215 HDF_LOGI("Usb serial ddk SetBaudRate.");
216 if (!VerifyPermission(PERMISSION_NAME)) {
217 HDF_LOGE("%{public}s: no permission", __func__);
218 return USB_SERIAL_DDK_NO_PERM;
219 }
220 if (osAdapter_ == nullptr) {
221 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
222 return USB_SERIAL_DDK_INVALID_OPERATION;
223 }
224 return osAdapter_->SetBaudRate(static_cast<int32_t>(dev.fd), baudRate);
225 }
226
SetParams(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev,const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialParams & params)227 int32_t UsbSerialDdkService::SetParams(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev,
228 const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialParams& params)
229 {
230 HDF_LOGI("Usb serial ddk SetParams.");
231 if (!VerifyPermission(PERMISSION_NAME)) {
232 HDF_LOGE("%{public}s: no permission", __func__);
233 return USB_SERIAL_DDK_NO_PERM;
234 }
235 if (osAdapter_ == nullptr) {
236 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
237 return USB_SERIAL_DDK_INVALID_OPERATION;
238 }
239 return osAdapter_->SetParams(static_cast<int32_t>(dev.fd), params);
240 }
241
SetTimeout(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev,int32_t timeout)242 int32_t UsbSerialDdkService::SetTimeout(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev,
243 int32_t timeout)
244 {
245 HDF_LOGI("Usb serial ddk SetTimeout.");
246 if (!VerifyPermission(PERMISSION_NAME)) {
247 HDF_LOGE("%{public}s: no permission", __func__);
248 return USB_SERIAL_DDK_NO_PERM;
249 }
250 const int maxTimeoutVal = 25500;
251 if (timeout < -1 || timeout > maxTimeoutVal) {
252 HDF_LOGE("timeout value %d error\n", timeout);
253 return USB_SERIAL_DDK_INVALID_PARAMETER;
254 }
255 if (osAdapter_ == nullptr) {
256 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
257 return USB_SERIAL_DDK_INVALID_OPERATION;
258 }
259 return osAdapter_->SetTimeout(static_cast<int32_t>(dev.fd), timeout);
260 }
261
SetFlowControl(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev,OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialFlowControl flowControl)262 int32_t UsbSerialDdkService::SetFlowControl(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev,
263 OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialFlowControl flowControl)
264 {
265 HDF_LOGI("Usb serial ddk SetFlowControl.");
266 if (!VerifyPermission(PERMISSION_NAME)) {
267 HDF_LOGE("%{public}s: no permission", __func__);
268 return USB_SERIAL_DDK_NO_PERM;
269 }
270 if (flowControl < USB_SERIAL_NO_FLOW_CONTROL || flowControl > USB_SERIAL_HARDWARE_FLOW_CONTROL) {
271 HDF_LOGE("Param flowControl err.\n");
272 return USB_SERIAL_DDK_INVALID_PARAMETER;
273 }
274 if (osAdapter_ == nullptr) {
275 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
276 return USB_SERIAL_DDK_INVALID_OPERATION;
277 }
278 return osAdapter_->SetFlowControl(static_cast<int32_t>(dev.fd), flowControl);
279 }
280
Flush(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev)281 int32_t UsbSerialDdkService::Flush(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev)
282 {
283 HDF_LOGI("Usb serial ddk Flush.");
284 if (!VerifyPermission(PERMISSION_NAME)) {
285 HDF_LOGE("%{public}s: no permission", __func__);
286 return USB_SERIAL_DDK_NO_PERM;
287 }
288 if (osAdapter_ == nullptr) {
289 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
290 return USB_SERIAL_DDK_INVALID_OPERATION;
291 }
292 return osAdapter_->Flush(static_cast<int32_t>(dev.fd));
293 }
294
FlushInput(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev)295 int32_t UsbSerialDdkService::FlushInput(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev)
296 {
297 HDF_LOGI("Usb serial ddk FlushInput.");
298 if (!VerifyPermission(PERMISSION_NAME)) {
299 HDF_LOGE("%{public}s: no permission", __func__);
300 return USB_SERIAL_DDK_NO_PERM;
301 }
302 if (osAdapter_ == nullptr) {
303 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
304 return USB_SERIAL_DDK_INVALID_OPERATION;
305 }
306 return osAdapter_->FlushInput(static_cast<int32_t>(dev.fd));
307 }
308
FlushOutput(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle & dev)309 int32_t UsbSerialDdkService::FlushOutput(const OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle &dev)
310 {
311 HDF_LOGI("Usb serial ddk FlushOutput.");
312 if (!VerifyPermission(PERMISSION_NAME)) {
313 HDF_LOGE("%{public}s: no permission", __func__);
314 return USB_SERIAL_DDK_NO_PERM;
315 }
316 if (osAdapter_ == nullptr) {
317 HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
318 return USB_SERIAL_DDK_INVALID_OPERATION;
319 }
320 return osAdapter_->FlushOutput(static_cast<int32_t>(dev.fd));
321 }
322
323 } // namespace V1_0
324 } // namespace UsbSerialDdk
325 } // namespace Usb
326 } // namespace HDI
327 } // namespace OHOS
328