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 using namespace OHOS::ExternalDeviceManager;
30 namespace {
31 OHOS::sptr<OHOS::HDI::Usb::Ddk::V1_0::IUsbDdk> g_ddk = nullptr;
32 } // namespace
OH_Usb_Init()33 int32_t OH_Usb_Init()
34 {
35 g_ddk = OHOS::HDI::Usb::Ddk::V1_0::IUsbDdk::Get();
36 if (g_ddk == nullptr) {
37 EDM_LOGE(MODULE_USB_DDK, "get ddk failed");
38 return USB_DDK_FAILED;
39 }
40
41 return g_ddk->Init();
42 }
43
OH_Usb_Release()44 void OH_Usb_Release()
45 {
46 if (g_ddk == nullptr) {
47 EDM_LOGE(MODULE_USB_DDK, "ddk is null");
48 return;
49 }
50 g_ddk->Release();
51 g_ddk.clear();
52 }
53
OH_Usb_GetDeviceDescriptor(uint64_t deviceId,UsbDeviceDescriptor * desc)54 int32_t OH_Usb_GetDeviceDescriptor(uint64_t deviceId, UsbDeviceDescriptor *desc)
55 {
56 if (g_ddk == nullptr) {
57 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
58 return USB_DDK_INVALID_OPERATION;
59 }
60 if (desc == nullptr) {
61 EDM_LOGE(MODULE_USB_DDK, "param is null");
62 return USB_DDK_INVALID_PARAMETER;
63 }
64
65 auto tmpDesc = reinterpret_cast<OHOS::HDI::Usb::Ddk::V1_0::UsbDeviceDescriptor *>(desc);
66 int32_t ret = g_ddk->GetDeviceDescriptor(deviceId, *tmpDesc);
67 if (ret != EDM_OK) {
68 EDM_LOGE(MODULE_USB_DDK, "get device desc failed: %{public}d", ret);
69 return ret;
70 }
71 return EDM_OK;
72 }
73
OH_Usb_GetConfigDescriptor(uint64_t deviceId,uint8_t configIndex,struct UsbDdkConfigDescriptor ** const config)74 int32_t OH_Usb_GetConfigDescriptor(
75 uint64_t deviceId, uint8_t configIndex, struct UsbDdkConfigDescriptor ** const config)
76 {
77 if (g_ddk == nullptr) {
78 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
79 return USB_DDK_INVALID_OPERATION;
80 }
81 if (config == nullptr) {
82 EDM_LOGE(MODULE_USB_DDK, "param is null");
83 return USB_DDK_INVALID_PARAMETER;
84 }
85 std::vector<uint8_t> configDescriptor;
86 int32_t ret = g_ddk->GetConfigDescriptor(deviceId, configIndex, configDescriptor);
87 if (ret != EDM_OK) {
88 EDM_LOGE(MODULE_USB_DDK, "get config desc failed");
89 return ret;
90 }
91
92 return ParseUsbConfigDescriptor(configDescriptor, config);
93 }
94
OH_Usb_FreeConfigDescriptor(UsbDdkConfigDescriptor * const config)95 void OH_Usb_FreeConfigDescriptor(UsbDdkConfigDescriptor * const config)
96 {
97 return FreeUsbConfigDescriptor(config);
98 }
99
OH_Usb_ClaimInterface(uint64_t deviceId,uint8_t interfaceIndex,uint64_t * interfaceHandle)100 int32_t OH_Usb_ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t *interfaceHandle)
101 {
102 if (g_ddk == nullptr) {
103 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
104 return USB_DDK_INVALID_OPERATION;
105 }
106 if (interfaceHandle == nullptr) {
107 EDM_LOGE(MODULE_USB_DDK, "param is null");
108 return USB_DDK_INVALID_PARAMETER;
109 }
110
111 return g_ddk->ClaimInterface(deviceId, interfaceIndex, *interfaceHandle);
112 }
113
OH_Usb_ReleaseInterface(uint64_t interfaceHandle)114 int32_t OH_Usb_ReleaseInterface(uint64_t interfaceHandle)
115 {
116 if (g_ddk == nullptr) {
117 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
118 return USB_DDK_INVALID_OPERATION;
119 }
120
121 return g_ddk->ReleaseInterface(interfaceHandle);
122 }
123
OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle,uint8_t settingIndex)124 int32_t OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex)
125 {
126 if (g_ddk == nullptr) {
127 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
128 return USB_DDK_INVALID_OPERATION;
129 }
130
131 return g_ddk->SelectInterfaceSetting(interfaceHandle, settingIndex);
132 }
133
OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle,uint8_t * settingIndex)134 int32_t OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t *settingIndex)
135 {
136 if (g_ddk == nullptr) {
137 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
138 return USB_DDK_INVALID_OPERATION;
139 }
140
141 if (settingIndex == nullptr) {
142 EDM_LOGE(MODULE_USB_DDK, "param is null");
143 return USB_DDK_INVALID_PARAMETER;
144 }
145
146 return g_ddk->GetCurrentInterfaceSetting(interfaceHandle, *settingIndex);
147 }
148
OH_Usb_SendControlReadRequest(uint64_t interfaceHandle,const UsbControlRequestSetup * setup,uint32_t timeout,uint8_t * data,uint32_t * dataLen)149 int32_t OH_Usb_SendControlReadRequest(
150 uint64_t interfaceHandle, const UsbControlRequestSetup *setup, uint32_t timeout, uint8_t *data, uint32_t *dataLen)
151 {
152 if (g_ddk == nullptr) {
153 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
154 return USB_DDK_INVALID_OPERATION;
155 }
156
157 if (setup == nullptr || data == nullptr || dataLen == nullptr) {
158 EDM_LOGE(MODULE_USB_DDK, "param is null");
159 return USB_DDK_INVALID_PARAMETER;
160 }
161
162 auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_0::UsbControlRequestSetup *>(setup);
163 std::vector<uint8_t> dataTmp;
164 int32_t ret = g_ddk->SendControlReadRequest(interfaceHandle, *tmpSetUp, timeout, dataTmp);
165 if (ret != 0) {
166 EDM_LOGE(MODULE_USB_DDK, "send control req failed");
167 return ret;
168 }
169
170 if (*dataLen < dataTmp.size()) {
171 EDM_LOGE(MODULE_USB_DDK, "The data is too small");
172 return USB_DDK_INVALID_PARAMETER;
173 }
174
175 if (memcpy_s(data, *dataLen, dataTmp.data(), dataTmp.size()) != 0) {
176 EDM_LOGE(MODULE_USB_DDK, "copy data failed");
177 return USB_DDK_MEMORY_ERROR;
178 }
179 *dataLen = dataTmp.size();
180 return EDM_OK;
181 }
182
OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle,const UsbControlRequestSetup * setup,uint32_t timeout,const uint8_t * data,uint32_t dataLen)183 int32_t OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle, const UsbControlRequestSetup *setup, uint32_t timeout,
184 const uint8_t *data, uint32_t dataLen)
185 {
186 if (g_ddk == nullptr) {
187 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
188 return USB_DDK_INVALID_OPERATION;
189 }
190
191 if (setup == nullptr || data == nullptr) {
192 EDM_LOGE(MODULE_USB_DDK, "param is null");
193 return USB_DDK_INVALID_PARAMETER;
194 }
195
196 auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_0::UsbControlRequestSetup *>(setup);
197 std::vector<uint8_t> dataTmp(data, data + dataLen);
198 return g_ddk->SendControlWriteRequest(interfaceHandle, *tmpSetUp, timeout, dataTmp);
199 }
200
OH_Usb_SendPipeRequest(const UsbRequestPipe * pipe,UsbDeviceMemMap * devMmap)201 int32_t OH_Usb_SendPipeRequest(const UsbRequestPipe *pipe, UsbDeviceMemMap *devMmap)
202 {
203 if (g_ddk == nullptr) {
204 EDM_LOGE(MODULE_USB_DDK, "invalid obj");
205 return USB_DDK_INVALID_OPERATION;
206 }
207
208 if (pipe == nullptr || devMmap == nullptr || devMmap->address == nullptr) {
209 EDM_LOGE(MODULE_USB_DDK, "param is null");
210 return USB_DDK_INVALID_PARAMETER;
211 }
212
213 auto tmpSetUp = reinterpret_cast<const OHOS::HDI::Usb::Ddk::V1_0::UsbRequestPipe *>(pipe);
214 return g_ddk->SendPipeRequest(
215 *tmpSetUp, devMmap->size, devMmap->offset, devMmap->bufferLength, devMmap->transferedLength);
216 }
217
OH_Usb_CreateDeviceMemMap(uint64_t deviceId,size_t size,UsbDeviceMemMap ** devMmap)218 int32_t OH_Usb_CreateDeviceMemMap(uint64_t deviceId, size_t size, UsbDeviceMemMap **devMmap)
219 {
220 if (devMmap == nullptr) {
221 EDM_LOGE(MODULE_USB_DDK, "invalid param");
222 return USB_DDK_INVALID_PARAMETER;
223 }
224
225 int32_t fd = -1;
226 int32_t ret = g_ddk->GetDeviceMemMapFd(deviceId, fd);
227 if (ret != EDM_OK) {
228 EDM_LOGE(MODULE_USB_DDK, "get fd failed, errno=%{public}d", errno);
229 return ret;
230 }
231 ftruncate(fd, size);
232
233 auto buffer = static_cast<uint8_t *>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
234 if (buffer == MAP_FAILED) {
235 EDM_LOGE(MODULE_USB_DDK, "mmap failed, errno=%{public}d", errno);
236 return USB_DDK_MEMORY_ERROR;
237 }
238
239 UsbDeviceMemMap *memMap = new UsbDeviceMemMap({buffer, size, 0, size, 0});
240 if (memMap == nullptr) {
241 EDM_LOGE(MODULE_USB_DDK, "alloc dev mem failed, errno=%{public}d", errno);
242 return USB_DDK_MEMORY_ERROR;
243 }
244
245 *devMmap = memMap;
246 return EDM_OK;
247 }
248
OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap * devMmap)249 void OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap *devMmap)
250 {
251 if (devMmap == nullptr) {
252 EDM_LOGE(MODULE_USB_DDK, "devMmap is nullptr");
253 return;
254 }
255
256 if (munmap(devMmap->address, devMmap->size) != 0) {
257 EDM_LOGE(MODULE_USB_DDK, "munmap failed, errno=%{public}d", errno);
258 return;
259 }
260 delete devMmap;
261 }