• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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_ddk_api.h"
17 #include <cerrno>
18 #include <memory.h>
19 #include <securec.h>
20 #include <sys/mman.h>
21 #include <unistd.h>
22 #include <vector>
23 #include <unordered_map>
24 
25 #include "edm_errors.h"
26 #include "hilog_wrapper.h"
27 #include "usb_config_desc_parser.h"
28 #include "usb_ddk_types.h"
29 #include "v1_1/usb_ddk_service.h"
30 
31 using namespace OHOS::ExternalDeviceManager;
32 namespace {
33 OHOS::sptr<OHOS::HDI::Usb::Ddk::V1_1::IUsbDdk> g_ddk = nullptr;
34 std::unordered_map<int32_t, int32_t> g_errorMap = {
35     {HDF_SUCCESS, USB_DDK_SUCCESS},
36     {HDF_ERR_NOT_SUPPORT, USB_DDK_INVALID_OPERATION},
37     {HDF_FAILURE, USB_DDK_INVALID_OPERATION},
38     {HDF_ERR_INVALID_PARAM, USB_DDK_INVALID_PARAMETER},
39     {HDF_ERR_BAD_FD, USB_DDK_INVALID_PARAMETER},
40     {HDF_ERR_NOPERM, USB_DDK_NO_PERM},
41     {HDF_DEV_ERR_NO_MEMORY, USB_DDK_MEMORY_ERROR},
42     {HDF_ERR_OUT_OF_RANGE, USB_DDK_MEMORY_ERROR},
43     {HDF_ERR_IO, USB_DDK_IO_FAILED},
44     {HDF_ERR_TIMEOUT, USB_DDK_TIMEOUT}
45 };
46 } // namespace
47 
TransToUsbCode(int32_t ret)48 static int32_t TransToUsbCode(int32_t ret)
49 {
50     if ((g_errorMap.find(ret) != g_errorMap.end())) {
51         return g_errorMap[ret];
52     } else {
53         return ret;
54     }
55 }
56 
OH_Usb_Init()57 int32_t OH_Usb_Init()
58 {
59     g_ddk = OHOS::HDI::Usb::Ddk::V1_1::IUsbDdk::Get();
60     if (g_ddk == nullptr) {
61         EDM_LOGE(MODULE_USB_DDK, "get ddk failed");
62         return USB_DDK_INVALID_OPERATION;
63     }
64 
65     return TransToUsbCode(g_ddk->Init());
66 }
67 
OH_Usb_Release()68 void OH_Usb_Release()
69 {
70     if (g_ddk == nullptr) {
71         EDM_LOGE(MODULE_USB_DDK, "ddk is null");
72         return;
73     }
74     g_ddk->Release();
75     g_ddk.clear();
76 }
77 
OH_Usb_ReleaseResource()78 int32_t OH_Usb_ReleaseResource()
79 {
80     if (g_ddk == nullptr) {
81         EDM_LOGE(MODULE_USB_DDK, "ddk is null");
82         return USB_DDK_INVALID_OPERATION;
83     }
84     int32_t ret = TransToUsbCode(g_ddk->Release());
85     if (ret != USB_DDK_SUCCESS) {
86         EDM_LOGE(MODULE_USB_DDK, "release failed: %{public}d", ret);
87     }
88     g_ddk.clear();
89     return ret;
90 }
91 
OH_Usb_GetDeviceDescriptor(uint64_t deviceId,UsbDeviceDescriptor * desc)92 int32_t OH_Usb_GetDeviceDescriptor(uint64_t deviceId, UsbDeviceDescriptor *desc)
93 {
94     if (g_ddk == nullptr) {
95         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
96         return USB_DDK_INVALID_OPERATION;
97     }
98     if (desc == nullptr) {
99         EDM_LOGE(MODULE_USB_DDK, "param is null");
100         return USB_DDK_INVALID_PARAMETER;
101     }
102 
103     auto tmpDesc = reinterpret_cast<OHOS::HDI::Usb::Ddk::V1_1::UsbDeviceDescriptor *>(desc);
104     int32_t ret = TransToUsbCode(g_ddk->GetDeviceDescriptor(deviceId, *tmpDesc));
105     if (ret != USB_DDK_SUCCESS) {
106         EDM_LOGE(MODULE_USB_DDK, "get device desc failed: %{public}d", ret);
107         return ret;
108     }
109     return USB_DDK_SUCCESS;
110 }
111 
OH_Usb_GetConfigDescriptor(uint64_t deviceId,uint8_t configIndex,struct UsbDdkConfigDescriptor ** const config)112 int32_t OH_Usb_GetConfigDescriptor(
113     uint64_t deviceId, uint8_t configIndex, struct UsbDdkConfigDescriptor ** const config)
114 {
115     if (g_ddk == nullptr) {
116         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
117         return USB_DDK_INVALID_OPERATION;
118     }
119     if (config == nullptr) {
120         EDM_LOGE(MODULE_USB_DDK, "param is null");
121         return USB_DDK_INVALID_PARAMETER;
122     }
123     std::vector<uint8_t> configDescriptor;
124     int32_t ret = TransToUsbCode(g_ddk->GetConfigDescriptor(deviceId, configIndex, configDescriptor));
125     if (ret != USB_DDK_SUCCESS) {
126         EDM_LOGE(MODULE_USB_DDK, "get config desc failed");
127         return ret;
128     }
129 
130     return ParseUsbConfigDescriptor(configDescriptor, config);
131 }
132 
OH_Usb_FreeConfigDescriptor(UsbDdkConfigDescriptor * const config)133 void OH_Usb_FreeConfigDescriptor(UsbDdkConfigDescriptor * const config)
134 {
135     return FreeUsbConfigDescriptor(config);
136 }
137 
OH_Usb_ClaimInterface(uint64_t deviceId,uint8_t interfaceIndex,uint64_t * interfaceHandle)138 int32_t OH_Usb_ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t *interfaceHandle)
139 {
140     if (g_ddk == nullptr) {
141         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
142         return USB_DDK_INVALID_OPERATION;
143     }
144     if (interfaceHandle == nullptr) {
145         EDM_LOGE(MODULE_USB_DDK, "param is null");
146         return USB_DDK_INVALID_PARAMETER;
147     }
148 
149     return TransToUsbCode(g_ddk->ClaimInterface(deviceId, interfaceIndex, *interfaceHandle));
150 }
151 
OH_Usb_ReleaseInterface(uint64_t interfaceHandle)152 int32_t OH_Usb_ReleaseInterface(uint64_t interfaceHandle)
153 {
154     if (g_ddk == nullptr) {
155         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
156         return USB_DDK_INVALID_OPERATION;
157     }
158 
159     return TransToUsbCode(g_ddk->ReleaseInterface(interfaceHandle));
160 }
161 
OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle,uint8_t settingIndex)162 int32_t OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex)
163 {
164     if (g_ddk == nullptr) {
165         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
166         return USB_DDK_INVALID_OPERATION;
167     }
168 
169     return TransToUsbCode(g_ddk->SelectInterfaceSetting(interfaceHandle, settingIndex));
170 }
171 
OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle,uint8_t * settingIndex)172 int32_t OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t *settingIndex)
173 {
174     if (g_ddk == nullptr) {
175         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
176         return USB_DDK_INVALID_OPERATION;
177     }
178 
179     if (settingIndex == nullptr) {
180         EDM_LOGE(MODULE_USB_DDK, "param is null");
181         return USB_DDK_INVALID_PARAMETER;
182     }
183 
184     return TransToUsbCode(g_ddk->GetCurrentInterfaceSetting(interfaceHandle, *settingIndex));
185 }
186 
OH_Usb_SendControlReadRequest(uint64_t interfaceHandle,const UsbControlRequestSetup * setup,uint32_t timeout,uint8_t * data,uint32_t * dataLen)187 int32_t OH_Usb_SendControlReadRequest(
188     uint64_t interfaceHandle, const UsbControlRequestSetup *setup, uint32_t timeout, uint8_t *data, uint32_t *dataLen)
189 {
190     if (g_ddk == nullptr) {
191         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
192         return USB_DDK_INVALID_OPERATION;
193     }
194 
195     if (setup == nullptr || data == nullptr || dataLen == nullptr) {
196         EDM_LOGE(MODULE_USB_DDK, "param is null");
197         return USB_DDK_INVALID_PARAMETER;
198     }
199 
200     auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_1::UsbControlRequestSetup *>(setup);
201     std::vector<uint8_t> dataTmp;
202     int32_t ret = TransToUsbCode(g_ddk->SendControlReadRequest(interfaceHandle, *tmpSetUp, timeout, dataTmp));
203     if (ret != 0) {
204         EDM_LOGE(MODULE_USB_DDK, "send control req failed");
205         return ret;
206     }
207 
208     if (*dataLen < dataTmp.size()) {
209         EDM_LOGE(MODULE_USB_DDK, "The data is too small");
210         return USB_DDK_INVALID_PARAMETER;
211     }
212 
213     if (memcpy_s(data, *dataLen, dataTmp.data(), dataTmp.size()) != 0) {
214         EDM_LOGE(MODULE_USB_DDK, "copy data failed");
215         return USB_DDK_MEMORY_ERROR;
216     }
217     *dataLen = dataTmp.size();
218     return USB_DDK_SUCCESS;
219 }
220 
OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle,const UsbControlRequestSetup * setup,uint32_t timeout,const uint8_t * data,uint32_t dataLen)221 int32_t OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle, const UsbControlRequestSetup *setup, uint32_t timeout,
222     const uint8_t *data, uint32_t dataLen)
223 {
224     if (g_ddk == nullptr) {
225         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
226         return USB_DDK_INVALID_OPERATION;
227     }
228 
229     if (setup == nullptr || data == nullptr) {
230         EDM_LOGE(MODULE_USB_DDK, "param is null");
231         return USB_DDK_INVALID_PARAMETER;
232     }
233 
234     auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_1::UsbControlRequestSetup *>(setup);
235     std::vector<uint8_t> dataTmp(data, data + dataLen);
236     return TransToUsbCode(g_ddk->SendControlWriteRequest(interfaceHandle, *tmpSetUp, timeout, dataTmp));
237 }
238 
OH_Usb_SendPipeRequest(const UsbRequestPipe * pipe,UsbDeviceMemMap * devMmap)239 int32_t OH_Usb_SendPipeRequest(const UsbRequestPipe *pipe, UsbDeviceMemMap *devMmap)
240 {
241     if (g_ddk == nullptr) {
242         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
243         return USB_DDK_INVALID_OPERATION;
244     }
245 
246     if (pipe == nullptr || devMmap == nullptr || devMmap->address == nullptr) {
247         EDM_LOGE(MODULE_USB_DDK, "param is null");
248         return USB_DDK_INVALID_PARAMETER;
249     }
250 
251     auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_1::UsbRequestPipe *>(pipe);
252     return TransToUsbCode(g_ddk->SendPipeRequest(
253         *tmpSetUp, devMmap->size, devMmap->offset, devMmap->bufferLength, devMmap->transferedLength));
254 }
255 
OH_Usb_SendPipeRequestWithAshmem(const UsbRequestPipe * pipe,DDK_Ashmem * ashmem)256 int32_t OH_Usb_SendPipeRequestWithAshmem(const UsbRequestPipe *pipe, DDK_Ashmem *ashmem)
257 {
258     if (g_ddk == nullptr) {
259         EDM_LOGE(MODULE_USB_DDK, "invalid obj");
260         return USB_DDK_INVALID_OPERATION;
261     }
262 
263     if (pipe == nullptr || ashmem == nullptr || ashmem->address == nullptr) {
264         EDM_LOGE(MODULE_USB_DDK, "param is null");
265         return USB_DDK_INVALID_PARAMETER;
266     }
267 
268     auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_1::UsbRequestPipe *>(pipe);
269     std::vector<uint8_t> address = std::vector<uint8_t>(ashmem->address, ashmem->address + ashmem->size);
270     OHOS::HDI::Usb::Ddk::V1_1::UsbAshmem usbAshmem = {ashmem->ashmemFd, address, ashmem->size, 0, ashmem->size, 0};
271     return TransToUsbCode(g_ddk->SendPipeRequestWithAshmem(*tmpSetUp, usbAshmem, ashmem->transferredLength));
272 }
273 
OH_Usb_CreateDeviceMemMap(uint64_t deviceId,size_t size,UsbDeviceMemMap ** devMmap)274 int32_t OH_Usb_CreateDeviceMemMap(uint64_t deviceId, size_t size, UsbDeviceMemMap **devMmap)
275 {
276     if (devMmap == nullptr) {
277         EDM_LOGE(MODULE_USB_DDK, "invalid param");
278         return USB_DDK_INVALID_PARAMETER;
279     }
280 
281     int32_t fd = -1;
282     int32_t ret = TransToUsbCode(g_ddk->GetDeviceMemMapFd(deviceId, fd));
283     if (ret != USB_DDK_SUCCESS) {
284         EDM_LOGE(MODULE_USB_DDK, "get fd failed, errno=%{public}d", errno);
285         return ret;
286     }
287     ftruncate(fd, size);
288 
289     auto buffer = static_cast<uint8_t *>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
290     if (buffer == MAP_FAILED) {
291         EDM_LOGE(MODULE_USB_DDK, "mmap failed, errno=%{public}d", errno);
292         return USB_DDK_MEMORY_ERROR;
293     }
294 
295     UsbDeviceMemMap *memMap = new UsbDeviceMemMap({buffer, size, 0, size, 0});
296     if (memMap == nullptr) {
297         EDM_LOGE(MODULE_USB_DDK, "alloc dev mem failed, errno=%{public}d", errno);
298         return USB_DDK_MEMORY_ERROR;
299     }
300 
301     *devMmap = memMap;
302     return USB_DDK_SUCCESS;
303 }
304 
OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap * devMmap)305 void OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap *devMmap)
306 {
307     if (devMmap == nullptr) {
308         EDM_LOGE(MODULE_USB_DDK, "devMmap is nullptr");
309         return;
310     }
311 
312     if (munmap(devMmap->address, devMmap->size) != 0) {
313         EDM_LOGE(MODULE_USB_DDK, "munmap failed, errno=%{public}d", errno);
314         return;
315     }
316     delete devMmap;
317 }
318 
OH_Usb_GetDevices(struct Usb_DeviceArray * devices)319 int32_t OH_Usb_GetDevices(struct Usb_DeviceArray *devices)
320 {
321     if (g_ddk == nullptr) {
322         EDM_LOGE(MODULE_USB_DDK, "%{public}s: invalid obj", __func__);
323         return USB_DDK_INVALID_OPERATION;
324     }
325     if (devices == nullptr) {
326         EDM_LOGE(MODULE_USB_DDK, "%{public}s: param is null", __func__);
327         return USB_DDK_INVALID_PARAMETER;
328     }
329 
330     std::vector<uint64_t> deviceIds;
331     int32_t ret = TransToUsbCode(g_ddk->GetDevices(deviceIds));
332     if (ret != USB_DDK_SUCCESS) {
333         EDM_LOGE(MODULE_USB_DDK, "%{public}s: get devices failed", __func__);
334         return ret;
335     }
336 
337     devices->num = deviceIds.size();
338     for (size_t i = 0; i < deviceIds.size(); i++) {
339         devices->deviceIds[i] = deviceIds[i];
340     }
341 
342     return USB_DDK_SUCCESS;
343 }