1 /*
2 * Copyright (c) 2023 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
24 #include "edm_errors.h"
25 #include "hilog_wrapper.h"
26 #include "usb_config_desc_parser.h"
27 #include "usb_ddk_types.h"
28 #include "v1_0/usb_ddk_service.h"
29 #include "ext_permission_manager.h"
30 using namespace OHOS::ExternalDeviceManager;
31 namespace {
32 OHOS::sptr<OHOS::HDI::Usb::Ddk::V1_0::IUsbDdk> g_ddk = nullptr;
33 } // namespace
34 static const std::string PERMISSION_NAME = "ohos.permission.ACCESS_DDK_USB";
OH_Usb_Init()35 int32_t OH_Usb_Init()
36 {
37 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
38 EDM_LOGE(MODULE_USB_DDK, "no permission");
39 return USB_DDK_FAILED;
40 }
41 g_ddk = OHOS::HDI::Usb::Ddk::V1_0::IUsbDdk::Get();
42 if (g_ddk == nullptr) {
43 EDM_LOGE(MODULE_USB_DDK, "get ddk failed");
44 return USB_DDK_FAILED;
45 }
46
47 return g_ddk->Init();
48 }
49
OH_Usb_Release()50 void OH_Usb_Release()
51 {
52 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
53 EDM_LOGE(MODULE_USB_DDK, "no permission");
54 return;
55 }
56 if (g_ddk == nullptr) {
57 EDM_LOGE(MODULE_USB_DDK, "ddk is null");
58 return;
59 }
60 g_ddk->Release();
61 g_ddk.clear();
62 }
63
OH_Usb_GetDeviceDescriptor(uint64_t deviceId,UsbDeviceDescriptor * desc)64 int32_t OH_Usb_GetDeviceDescriptor(uint64_t deviceId, UsbDeviceDescriptor *desc)
65 {
66 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
67 EDM_LOGE(MODULE_USB_DDK, "no permission");
68 return USB_DDK_FAILED;
69 }
70 if (g_ddk == nullptr) {
71 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
72 return USB_DDK_INVALID_OPERATION;
73 }
74 if (desc == nullptr) {
75 EDM_LOGE(MODULE_USB_DDK, "param is null");
76 return USB_DDK_INVALID_PARAMETER;
77 }
78
79 auto tmpDesc = reinterpret_cast<OHOS::HDI::Usb::Ddk::V1_0::UsbDeviceDescriptor *>(desc);
80 int32_t ret = g_ddk->GetDeviceDescriptor(deviceId, *tmpDesc);
81 if (ret != EDM_OK) {
82 EDM_LOGE(MODULE_USB_DDK, "get device desc failed: %{public}d", ret);
83 return ret;
84 }
85 return EDM_OK;
86 }
87
OH_Usb_GetConfigDescriptor(uint64_t deviceId,uint8_t configIndex,struct UsbDdkConfigDescriptor ** const config)88 int32_t OH_Usb_GetConfigDescriptor(
89 uint64_t deviceId, uint8_t configIndex, struct UsbDdkConfigDescriptor ** const config)
90 {
91 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
92 EDM_LOGE(MODULE_USB_DDK, "no permission");
93 return USB_DDK_FAILED;
94 }
95 if (g_ddk == nullptr) {
96 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
97 return USB_DDK_INVALID_OPERATION;
98 }
99 if (config == nullptr) {
100 EDM_LOGE(MODULE_USB_DDK, "param is null");
101 return USB_DDK_INVALID_PARAMETER;
102 }
103 std::vector<uint8_t> configDescriptor;
104 int32_t ret = g_ddk->GetConfigDescriptor(deviceId, configIndex, configDescriptor);
105 if (ret != EDM_OK) {
106 EDM_LOGE(MODULE_USB_DDK, "get config desc failed");
107 return ret;
108 }
109
110 return ParseUsbConfigDescriptor(configDescriptor, config);
111 }
112
OH_Usb_FreeConfigDescriptor(UsbDdkConfigDescriptor * const config)113 void OH_Usb_FreeConfigDescriptor(UsbDdkConfigDescriptor * const config)
114 {
115 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
116 EDM_LOGE(MODULE_USB_DDK, "no permission");
117 return;
118 }
119 return FreeUsbConfigDescriptor(config);
120 }
121
OH_Usb_ClaimInterface(uint64_t deviceId,uint8_t interfaceIndex,uint64_t * interfaceHandle)122 int32_t OH_Usb_ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t *interfaceHandle)
123 {
124 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
125 EDM_LOGE(MODULE_USB_DDK, "no permission");
126 return USB_DDK_FAILED;
127 }
128 if (g_ddk == nullptr) {
129 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
130 return USB_DDK_INVALID_OPERATION;
131 }
132 if (interfaceHandle == nullptr) {
133 EDM_LOGE(MODULE_USB_DDK, "param is null");
134 return USB_DDK_INVALID_PARAMETER;
135 }
136
137 return g_ddk->ClaimInterface(deviceId, interfaceIndex, *interfaceHandle);
138 }
139
OH_Usb_ReleaseInterface(uint64_t interfaceHandle)140 int32_t OH_Usb_ReleaseInterface(uint64_t interfaceHandle)
141 {
142 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
143 EDM_LOGE(MODULE_USB_DDK, "no permission");
144 return USB_DDK_FAILED;
145 }
146 if (g_ddk == nullptr) {
147 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
148 return USB_DDK_INVALID_OPERATION;
149 }
150
151 return g_ddk->ReleaseInterface(interfaceHandle);
152 }
153
OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle,uint8_t settingIndex)154 int32_t OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex)
155 {
156 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
157 EDM_LOGE(MODULE_USB_DDK, "no permission");
158 return USB_DDK_FAILED;
159 }
160 if (g_ddk == nullptr) {
161 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
162 return USB_DDK_INVALID_OPERATION;
163 }
164
165 return g_ddk->SelectInterfaceSetting(interfaceHandle, settingIndex);
166 }
167
OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle,uint8_t * settingIndex)168 int32_t OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t *settingIndex)
169 {
170 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
171 EDM_LOGE(MODULE_USB_DDK, "no permission");
172 return USB_DDK_FAILED;
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 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 (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
191 EDM_LOGE(MODULE_USB_DDK, "no permission");
192 return USB_DDK_FAILED;
193 }
194 if (g_ddk == nullptr) {
195 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
196 return USB_DDK_INVALID_OPERATION;
197 }
198
199 if (setup == nullptr || data == nullptr || dataLen == nullptr) {
200 EDM_LOGE(MODULE_USB_DDK, "param is null");
201 return USB_DDK_INVALID_PARAMETER;
202 }
203
204 auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_0::UsbControlRequestSetup *>(setup);
205 std::vector<uint8_t> dataTmp;
206 int32_t ret = g_ddk->SendControlReadRequest(interfaceHandle, *tmpSetUp, timeout, dataTmp);
207 if (ret != 0) {
208 EDM_LOGE(MODULE_USB_DDK, "send control req failed");
209 return ret;
210 }
211
212 if (*dataLen < dataTmp.size()) {
213 EDM_LOGE(MODULE_USB_DDK, "The data is too small");
214 return USB_DDK_INVALID_PARAMETER;
215 }
216
217 if (memcpy_s(data, *dataLen, dataTmp.data(), dataTmp.size()) != 0) {
218 EDM_LOGE(MODULE_USB_DDK, "copy data failed");
219 return USB_DDK_MEMORY_ERROR;
220 }
221 *dataLen = dataTmp.size();
222 return EDM_OK;
223 }
224
OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle,const UsbControlRequestSetup * setup,uint32_t timeout,const uint8_t * data,uint32_t dataLen)225 int32_t OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle, const UsbControlRequestSetup *setup, uint32_t timeout,
226 const uint8_t *data, uint32_t dataLen)
227 {
228 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
229 EDM_LOGE(MODULE_USB_DDK, "no permission");
230 return USB_DDK_FAILED;
231 }
232 if (g_ddk == nullptr) {
233 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
234 return USB_DDK_INVALID_OPERATION;
235 }
236
237 if (setup == nullptr || data == nullptr) {
238 EDM_LOGE(MODULE_USB_DDK, "param is null");
239 return USB_DDK_INVALID_PARAMETER;
240 }
241
242 auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_0::UsbControlRequestSetup *>(setup);
243 std::vector<uint8_t> dataTmp(data, data + dataLen);
244 return g_ddk->SendControlWriteRequest(interfaceHandle, *tmpSetUp, timeout, dataTmp);
245 }
246
OH_Usb_SendPipeRequest(const UsbRequestPipe * pipe,UsbDeviceMemMap * devMmap)247 int32_t OH_Usb_SendPipeRequest(const UsbRequestPipe *pipe, UsbDeviceMemMap *devMmap)
248 {
249 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
250 EDM_LOGE(MODULE_USB_DDK, "no permission");
251 return USB_DDK_FAILED;
252 }
253 if (g_ddk == nullptr) {
254 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
255 return USB_DDK_INVALID_OPERATION;
256 }
257
258 if (pipe == nullptr || devMmap == nullptr || devMmap->address == nullptr) {
259 EDM_LOGE(MODULE_USB_DDK, "param is null");
260 return USB_DDK_INVALID_PARAMETER;
261 }
262
263 auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_0::UsbRequestPipe *>(pipe);
264 return g_ddk->SendPipeRequest(
265 *tmpSetUp, devMmap->size, devMmap->offset, devMmap->bufferLength, devMmap->transferedLength);
266 }
267
OH_Usb_CreateDeviceMemMap(uint64_t deviceId,size_t size,UsbDeviceMemMap ** devMmap)268 int32_t OH_Usb_CreateDeviceMemMap(uint64_t deviceId, size_t size, UsbDeviceMemMap **devMmap)
269 {
270 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
271 EDM_LOGE(MODULE_USB_DDK, "no permission");
272 return USB_DDK_FAILED;
273 }
274 if (devMmap == nullptr) {
275 EDM_LOGE(MODULE_USB_DDK, "invalid param");
276 return USB_DDK_INVALID_PARAMETER;
277 }
278
279 int32_t fd = -1;
280 int32_t ret = g_ddk->GetDeviceMemMapFd(deviceId, fd);
281 if (ret != EDM_OK) {
282 EDM_LOGE(MODULE_USB_DDK, "get fd failed, errno=%{public}d", errno);
283 return ret;
284 }
285 ftruncate(fd, size);
286
287 auto buffer = static_cast<uint8_t *>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
288 if (buffer == MAP_FAILED) {
289 EDM_LOGE(MODULE_USB_DDK, "mmap failed, errno=%{public}d", errno);
290 return USB_DDK_MEMORY_ERROR;
291 }
292
293 UsbDeviceMemMap *memMap = new UsbDeviceMemMap({buffer, size, 0, size, 0});
294 if (memMap == nullptr) {
295 EDM_LOGE(MODULE_USB_DDK, "alloc dev mem failed, errno=%{public}d", errno);
296 return USB_DDK_MEMORY_ERROR;
297 }
298
299 *devMmap = memMap;
300 return EDM_OK;
301 }
302
OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap * devMmap)303 void OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap *devMmap)
304 {
305 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
306 EDM_LOGE(MODULE_USB_DDK, "no permission");
307 return;
308 }
309 if (devMmap == nullptr) {
310 EDM_LOGE(MODULE_USB_DDK, "devMmap is nullptr");
311 return;
312 }
313
314 if (munmap(devMmap->address, devMmap->size) != 0) {
315 EDM_LOGE(MODULE_USB_DDK, "munmap failed, errno=%{public}d", errno);
316 return;
317 }
318 delete devMmap;
319 }