• 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 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 }