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