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_api.h"
17 #include <cerrno>
18 #include <iproxy_broker.h>
19 #include <memory.h>
20 #include <securec.h>
21 #include <sys/mman.h>
22 #include <unistd.h>
23 #include <vector>
24 #include <unordered_map>
25
26 #include "hilog_wrapper.h"
27 #include "v1_0/iusb_serial_ddk.h"
28 #include "ipc_error_code.h"
29
30 using namespace OHOS;
31 using namespace OHOS::ExternalDeviceManager;
32 namespace {
33 OHOS::sptr<OHOS::HDI::Usb::UsbSerialDdk::V1_0::IUsbSerialDdk> g_serialDdk = nullptr;
34 static OHOS::sptr<IRemoteObject::DeathRecipient> recipient_ = nullptr;
35 std::mutex g_mutex;
36
37 constexpr uint32_t MAX_BUFFER_SIZE = 4096;
38 } // namespace
39
40 struct UsbSerial_Device {
41 OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialDeviceHandle impl;
42
UsbSerial_DeviceUsbSerial_Device43 UsbSerial_Device()
44 {
45 impl.fd = -1;
46 }
47 } __attribute__ ((aligned(8)));
48
NewSerialDeviceHandle()49 UsbSerial_Device *NewSerialDeviceHandle()
50 {
51 return new UsbSerial_Device;
52 }
53
DeleteUsbSerialDeviceHandle(UsbSerial_Device ** dev)54 void DeleteUsbSerialDeviceHandle(UsbSerial_Device **dev)
55 {
56 if (*dev != nullptr) {
57 delete *dev;
58 *dev = nullptr;
59 }
60 }
61
SetDdk(OHOS::sptr<OHOS::HDI::Usb::UsbSerialDdk::V1_0::IUsbSerialDdk> & ddk)62 void SetDdk(OHOS::sptr<OHOS::HDI::Usb::UsbSerialDdk::V1_0::IUsbSerialDdk> &ddk)
63 {
64 g_serialDdk = ddk;
65 }
66
TransToUsbSerialCode(int32_t ret)67 static int32_t TransToUsbSerialCode(int32_t ret)
68 {
69 if (ret == HDF_SUCCESS) {
70 return USB_SERIAL_DDK_SUCCESS;
71 }
72 if (ret >= OH_IPC_ERROR_CODE_BASE && ret <= OH_IPC_ERROR_CODE_MAX) {
73 return USB_SERIAL_DDK_SERVICE_ERROR;
74 }
75 return ret;
76 }
77
78 class UsbSerialDeathRecipient : public IRemoteObject::DeathRecipient {
79 public:
80 void OnRemoteDied(const wptr<IRemoteObject> &object) override;
81 };
82
OnRemoteDied(const wptr<IRemoteObject> & object)83 void UsbSerialDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
84 {
85 std::lock_guard<std::mutex> lock(g_mutex);
86 EDM_LOGI(MODULE_USB_SERIAL_DDK, "usbSerial_ddk remote died");
87 if (g_serialDdk == nullptr) {
88 return;
89 }
90 auto remote = OHOS::HDI::hdi_objcast<OHOS::HDI::Usb::UsbSerialDdk::V1_0::IUsbSerialDdk>(g_serialDdk);
91 remote->RemoveDeathRecipient(recipient_);
92 recipient_.clear();
93 g_serialDdk = nullptr;
94 EDM_LOGI(MODULE_USB_SERIAL_DDK, "remove death recipient success");
95 }
96
OH_UsbSerial_Init()97 int32_t OH_UsbSerial_Init()
98 {
99 g_serialDdk = OHOS::HDI::Usb::UsbSerialDdk::V1_0::IUsbSerialDdk::Get();
100 if (g_serialDdk == nullptr) {
101 EDM_LOGE(MODULE_USB_SERIAL_DDK, "get ddk failed");
102 return USB_SERIAL_DDK_INIT_ERROR;
103 }
104 recipient_ = new UsbSerialDeathRecipient();
105 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<OHOS::HDI::Usb::UsbSerialDdk::V1_0::IUsbSerialDdk>(g_serialDdk);
106 if (!remote->AddDeathRecipient(recipient_)) {
107 EDM_LOGE(MODULE_USB_SERIAL_DDK, "add DeathRecipient failed");
108 return USB_SERIAL_DDK_INIT_ERROR;
109 }
110 return TransToUsbSerialCode(g_serialDdk->Init());
111 }
112
OH_UsbSerial_Release()113 int32_t OH_UsbSerial_Release()
114 {
115 if (g_serialDdk == nullptr) {
116 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
117 return USB_SERIAL_DDK_INIT_ERROR;
118 }
119 int32_t ret = g_serialDdk->Release();
120 g_serialDdk.clear();
121 return TransToUsbSerialCode(ret);
122 }
123
OH_UsbSerial_Open(uint64_t deviceId,uint8_t interfaceIndex,UsbSerial_Device ** dev)124 int32_t OH_UsbSerial_Open(uint64_t deviceId, uint8_t interfaceIndex, UsbSerial_Device **dev)
125 {
126 if (g_serialDdk == nullptr) {
127 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
128 return USB_SERIAL_DDK_INIT_ERROR;
129 }
130 if (dev == nullptr) {
131 EDM_LOGE(MODULE_USB_SERIAL_DDK, "dev is null");
132 return USB_SERIAL_DDK_INVALID_PARAMETER;
133 }
134 *dev = NewSerialDeviceHandle();
135 if (*dev == nullptr) {
136 EDM_LOGE(MODULE_USB_SERIAL_DDK, "Failed to allocate memory for device, errno=%{public}d", errno);
137 return USB_SERIAL_DDK_MEMORY_ERROR;
138 }
139 return TransToUsbSerialCode(g_serialDdk->Open(deviceId, interfaceIndex, (*dev)->impl));
140 }
141
OH_UsbSerial_Close(UsbSerial_Device ** dev)142 int32_t OH_UsbSerial_Close(UsbSerial_Device **dev)
143 {
144 if (g_serialDdk == nullptr) {
145 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
146 return USB_SERIAL_DDK_INIT_ERROR;
147 }
148 if (dev == nullptr || *dev == nullptr) {
149 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
150 return USB_SERIAL_DDK_INVALID_PARAMETER;
151 }
152 int32_t ret = g_serialDdk->Close((*dev)->impl);
153 DeleteUsbSerialDeviceHandle(dev);
154 return TransToUsbSerialCode(ret);
155 }
156
OH_UsbSerial_Read(UsbSerial_Device * dev,uint8_t * buff,uint32_t bufferSize,uint32_t * bytesRead)157 int32_t OH_UsbSerial_Read(UsbSerial_Device *dev, uint8_t *buff, uint32_t bufferSize, uint32_t *bytesRead)
158 {
159 if (g_serialDdk == nullptr) {
160 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
161 return USB_SERIAL_DDK_INIT_ERROR;
162 }
163 if (dev == nullptr || buff == nullptr || bufferSize == 0 || bytesRead == nullptr) {
164 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
165 return USB_SERIAL_DDK_INVALID_PARAMETER;
166 }
167 uint32_t readBufferSize = bufferSize;
168 if (readBufferSize > MAX_BUFFER_SIZE) {
169 readBufferSize = MAX_BUFFER_SIZE;
170 }
171 std::vector<uint8_t> readBuff;
172 int32_t ret = g_serialDdk->Read(dev->impl, readBufferSize, readBuff);
173 if (ret != HDF_SUCCESS) {
174 EDM_LOGE(MODULE_USB_SERIAL_DDK, "read error.");
175 return TransToUsbSerialCode(ret);
176 }
177 *bytesRead = readBuff.size();
178 if (readBuff.empty()) {
179 return USB_SERIAL_DDK_SUCCESS;
180 }
181 errno_t err = memcpy_s(buff, bufferSize, readBuff.data(), readBuff.size());
182 if (err != 0) {
183 EDM_LOGE(MODULE_USB_SERIAL_DDK, "memcpy_s error: %{public}d.", err);
184 return USB_SERIAL_DDK_MEMORY_ERROR;
185 }
186 return USB_SERIAL_DDK_SUCCESS;
187 }
188
OH_UsbSerial_Write(UsbSerial_Device * dev,uint8_t * buff,uint32_t bufferSize,uint32_t * bytesWritten)189 int32_t OH_UsbSerial_Write(UsbSerial_Device *dev, uint8_t *buff, uint32_t bufferSize, uint32_t *bytesWritten)
190 {
191 if (g_serialDdk == nullptr) {
192 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
193 return USB_SERIAL_DDK_INIT_ERROR;
194 }
195 if (dev == nullptr || buff == nullptr || bufferSize == 0 || bytesWritten == nullptr) {
196 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
197 return USB_SERIAL_DDK_INVALID_PARAMETER;
198 }
199 std::vector<uint8_t> writeBuff(buff, buff + bufferSize);
200 int32_t ret = g_serialDdk->Write(dev->impl, writeBuff, *bytesWritten);
201 if (ret != HDF_SUCCESS) {
202 EDM_LOGE(MODULE_USB_SERIAL_DDK, "write error.");
203 *bytesWritten = 0;
204 return TransToUsbSerialCode(ret);
205 }
206 return USB_SERIAL_DDK_SUCCESS;
207 }
208
OH_UsbSerial_SetBaudRate(UsbSerial_Device * dev,uint32_t baudRate)209 int32_t OH_UsbSerial_SetBaudRate(UsbSerial_Device *dev, uint32_t baudRate)
210 {
211 if (g_serialDdk == nullptr) {
212 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
213 return USB_SERIAL_DDK_INIT_ERROR;
214 }
215 if (dev == nullptr) {
216 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
217 return USB_SERIAL_DDK_INVALID_PARAMETER;
218 }
219 return TransToUsbSerialCode(g_serialDdk->SetBaudRate(dev->impl, baudRate));
220 }
221
OH_UsbSerial_SetParams(UsbSerial_Device * dev,UsbSerial_Params * params)222 int32_t OH_UsbSerial_SetParams(UsbSerial_Device *dev, UsbSerial_Params *params)
223 {
224 if (g_serialDdk == nullptr) {
225 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
226 return USB_SERIAL_DDK_INIT_ERROR;
227 }
228 if (dev == nullptr || params == nullptr) {
229 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
230 return USB_SERIAL_DDK_INVALID_PARAMETER;
231 }
232 OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialParams hidParams;
233 hidParams.baudRate = params->baudRate;
234 hidParams.nDataBits = params->nDataBits;
235 hidParams.nStopBits = params->nStopBits;
236 hidParams.parity = static_cast<OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialParity>(params->parity);
237 return TransToUsbSerialCode(g_serialDdk->SetParams(dev->impl, hidParams));
238 }
239
OH_UsbSerial_SetTimeout(UsbSerial_Device * dev,int timeout)240 int32_t OH_UsbSerial_SetTimeout(UsbSerial_Device *dev, int timeout)
241 {
242 if (g_serialDdk == nullptr) {
243 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
244 return USB_SERIAL_DDK_INIT_ERROR;
245 }
246 if (dev == nullptr) {
247 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
248 return USB_SERIAL_DDK_INVALID_PARAMETER;
249 }
250 return TransToUsbSerialCode(g_serialDdk->SetTimeout(dev->impl, timeout));
251 }
252
OH_UsbSerial_SetFlowControl(UsbSerial_Device * dev,UsbSerial_FlowControl flowControl)253 int32_t OH_UsbSerial_SetFlowControl(UsbSerial_Device *dev, UsbSerial_FlowControl flowControl)
254 {
255 if (g_serialDdk == nullptr) {
256 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
257 return USB_SERIAL_DDK_INIT_ERROR;
258 }
259 if (dev == nullptr) {
260 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
261 return USB_SERIAL_DDK_INVALID_PARAMETER;
262 }
263 auto hdiFlowControl = (OHOS::HDI::Usb::UsbSerialDdk::V1_0::UsbSerialFlowControl)flowControl;
264 return TransToUsbSerialCode(g_serialDdk->SetFlowControl(dev->impl, hdiFlowControl));
265 }
266
OH_UsbSerial_Flush(UsbSerial_Device * dev)267 int32_t OH_UsbSerial_Flush(UsbSerial_Device *dev)
268 {
269 if (g_serialDdk == nullptr) {
270 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
271 return USB_SERIAL_DDK_INIT_ERROR;
272 }
273 if (dev == nullptr) {
274 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
275 return USB_SERIAL_DDK_INVALID_PARAMETER;
276 }
277 return TransToUsbSerialCode(g_serialDdk->Flush(dev->impl));
278 }
279
OH_UsbSerial_FlushInput(UsbSerial_Device * dev)280 int32_t OH_UsbSerial_FlushInput(UsbSerial_Device *dev)
281 {
282 if (g_serialDdk == nullptr) {
283 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
284 return USB_SERIAL_DDK_INIT_ERROR;
285 }
286 if (dev == nullptr) {
287 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
288 return USB_SERIAL_DDK_INVALID_PARAMETER;
289 }
290 return TransToUsbSerialCode(g_serialDdk->FlushInput(dev->impl));
291 }
292
OH_UsbSerial_FlushOutput(UsbSerial_Device * dev)293 int32_t OH_UsbSerial_FlushOutput(UsbSerial_Device *dev)
294 {
295 if (g_serialDdk == nullptr) {
296 EDM_LOGE(MODULE_USB_SERIAL_DDK, "ddk is null");
297 return USB_SERIAL_DDK_INIT_ERROR;
298 }
299 if (dev == nullptr) {
300 EDM_LOGE(MODULE_USB_SERIAL_DDK, "param is null");
301 return USB_SERIAL_DDK_INVALID_PARAMETER;
302 }
303 return TransToUsbSerialCode(g_serialDdk->FlushOutput(dev->impl));
304 }
305