• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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