• 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 "v1_0/usb_ddk_service.h"
17 
18 #include <hdf_base.h>
19 #include <iproxy_broker.h>
20 
21 #include "ddk_pnp_listener_mgr.h"
22 #include "usb_ddk_hash.h"
23 #include "usb_ddk_interface.h"
24 #include "usb_raw_api.h"
25 #define HDF_LOG_TAG usb_ddk_service
26 
27 namespace OHOS {
28 namespace HDI {
29 namespace Usb {
30 namespace Ddk {
31 namespace V1_0 {
32 // 32 means size of uint32_t
33 #define GET_BUS_NUM(devHandle)          ((uint8_t)((devHandle) >> 32))
34 #define GET_DEV_NUM(devHandle)          ((uint8_t)((devHandle)&0xFFFFFFFF))
35 #define USB_RECIP_MASK                  0x1F
36 #define GET_CTRL_REQ_RECIP(requestType) ((requestType)&USB_RECIP_MASK)
37 #define TRANS_DIRECTION_OFFSET          7
38 #define GET_CTRL_REQ_DIR(requestType)   ((requestType) >> TRANS_DIRECTION_OFFSET)
39 #define REQ_TYPE_OFFERT                 5
40 #define REQ_TYPE_MASK                   0x3
41 #define GET_CTRL_REQ_TYPE(requestType)  (((requestType) >> REQ_TYPE_OFFERT) & REQ_TYPE_MASK)
42 
43 #define MAX_BUFF_SIZE         16384
44 #define MAX_CONTROL_BUFF_SIZE 1024
45 
UsbDdkImplGetInstance(void)46 extern "C" IUsbDdk *UsbDdkImplGetInstance(void)
47 {
48     return new (std::nothrow) UsbDdkService();
49 }
50 
ReleaseUsbInterface(uint64_t interfaceHandle)51 int32_t ReleaseUsbInterface(uint64_t interfaceHandle)
52 {
53     uint64_t handle = 0;
54     int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
55     if (ret != HDF_SUCCESS) {
56         HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
57         return ret;
58     }
59     UsbDdkDelHashRecord(interfaceHandle);
60 
61     struct UsbInterface *interface = nullptr;
62     const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
63     ret = GetInterfaceByHandle(handleConvert, &interface);
64     if (ret != HDF_SUCCESS) {
65         HDF_LOGE("%{public}s get interface failed %{public}d", __func__, ret);
66         return ret;
67     }
68 
69     ret = UsbCloseInterface(handleConvert);
70     if (ret != HDF_SUCCESS) {
71         HDF_LOGE("%{public}s close interface failed %{public}d", __func__, ret);
72         return ret;
73     }
74 
75     return UsbReleaseInterface(interface);
76 }
77 
UsbdPnpEventHandler(void * priv,uint32_t id,HdfSBuf * data)78 static int32_t UsbdPnpEventHandler(void *priv, uint32_t id, HdfSBuf *data)
79 {
80     if (id == USB_PNP_NOTIFY_REMOVE_DEVICE) {
81         uint32_t infoSize;
82         struct UsbPnpNotifyMatchInfoTable *infoTable = NULL;
83         auto flag = HdfSbufReadBuffer(data, (const void **)(&infoTable), &infoSize);
84         if ((!flag) || (infoTable == NULL)) {
85             HDF_LOGE("%{public}s: fail to read infoTable in event data, flag = %{public}d", __func__, flag);
86             return HDF_ERR_INVALID_PARAM;
87         }
88 
89         HDF_LOGI("%{public}s: delete record success", __func__);
90         ReleaseUsbInterface(UsbDdkGetRecordByVal({0, infoTable->busNum, infoTable->devNum}));
91     }
92     return HDF_SUCCESS;
93 }
94 
95 static HdfDevEventlistener *g_pnpListener = nullptr;
96 
Init()97 int32_t UsbDdkService::Init()
98 {
99     HDF_LOGI("usb ddk init");
100     if (g_pnpListener == nullptr) {
101         g_pnpListener = new HdfDevEventlistener();
102         if (g_pnpListener == nullptr) {
103             HDF_LOGE("%{public}s: create listener failed", __func__);
104             return HDF_ERR_MALLOC_FAIL;
105         }
106         g_pnpListener->callBack = UsbdPnpEventHandler;
107         if (DdkListenerMgrAdd(g_pnpListener) != HDF_SUCCESS) {
108             HDF_LOGE("%{public}s: add listener failed", __func__);
109             return HDF_FAILURE;
110         }
111     }
112 
113     return UsbInitHostSdk(nullptr);
114 }
115 
Release()116 int32_t UsbDdkService::Release()
117 {
118     HDF_LOGI("usb ddk exit");
119     return UsbExitHostSdk(nullptr);
120 }
121 
GetDeviceDescriptor(uint64_t deviceId,UsbDeviceDescriptor & desc)122 int32_t UsbDdkService::GetDeviceDescriptor(uint64_t deviceId, UsbDeviceDescriptor &desc)
123 {
124     UsbRawHandle *rawHandle = UsbRawOpenDevice(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId));
125     if (rawHandle == nullptr) {
126         HDF_LOGE("%{public}s open device failed", __func__);
127         return HDF_FAILURE;
128     }
129 
130     UsbRawDevice *rawDevice = UsbRawGetDevice(rawHandle);
131     if (rawDevice == nullptr) {
132         HDF_LOGE("%{public}s get device failed", __func__);
133         (void)UsbRawCloseDevice(rawHandle);
134         return HDF_FAILURE;
135     }
136 
137     int32_t ret = UsbRawGetDeviceDescriptor(rawDevice, reinterpret_cast<::UsbDeviceDescriptor *>(&desc));
138     if (ret != HDF_SUCCESS) {
139         HDF_LOGW("%{public}s get desc failed %{public}d", __func__, ret);
140     }
141     (void)UsbRawCloseDevice(rawHandle);
142     return ret;
143 }
144 
GetConfigDescriptor(uint64_t deviceId,uint8_t configIndex,std::vector<uint8_t> & configDesc)145 int32_t UsbDdkService::GetConfigDescriptor(uint64_t deviceId, uint8_t configIndex, std::vector<uint8_t> &configDesc)
146 {
147     UsbRawHandle *rawHandle = UsbRawOpenDevice(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId));
148     if (rawHandle == nullptr) {
149         HDF_LOGE("%{public}s open device failed", __func__);
150         return HDF_FAILURE;
151     }
152 
153     struct UsbConfigDescriptor tmpDesc {};
154     int32_t ret = GetRawConfigDescriptor(
155         rawHandle, configIndex, reinterpret_cast<uint8_t *>(&tmpDesc), sizeof(struct UsbConfigDescriptor));
156     if (ret <= 0) {
157         HDF_LOGW("%{public}s get config desc failed %{public}d", __func__, ret);
158         (void)UsbRawCloseDevice(rawHandle);
159         return ret;
160     }
161 
162     std::vector<uint8_t> tmpBuffer(tmpDesc.wTotalLength);
163     ret = GetRawConfigDescriptor(rawHandle, configIndex, tmpBuffer.data(), tmpDesc.wTotalLength);
164     if (ret <= 0) {
165         HDF_LOGW("%{public}s get config desc failed %{public}d", __func__, ret);
166         (void)UsbRawCloseDevice(rawHandle);
167         return ret;
168     }
169 
170     if (static_cast<size_t>(ret) != tmpBuffer.size()) {
171         HDF_LOGE("%{public}s config desc invalid length : %{public}d, bufferSize:%{public}zu", __func__, ret,
172             tmpBuffer.size());
173         return HDF_FAILURE;
174     }
175 
176     configDesc = tmpBuffer;
177 
178     (void)UsbRawCloseDevice(rawHandle);
179     return HDF_SUCCESS;
180 }
181 
ClaimInterface(uint64_t deviceId,uint8_t interfaceIndex,uint64_t & interfaceHandle)182 int32_t UsbDdkService::ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t &interfaceHandle)
183 {
184     struct UsbInterface *interface =
185         UsbClaimInterface(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId), interfaceIndex);
186     if (interface == nullptr) {
187         HDF_LOGE("%{public}s claim failed", __func__);
188         return HDF_FAILURE;
189     }
190 
191     UsbInterfaceHandle *handle = UsbOpenInterface(interface);
192     if (handle == nullptr) {
193         HDF_LOGE("%{public}s open failed", __func__);
194         return HDF_FAILURE;
195     }
196 
197     int32_t ret = UsbDdkHash({(uint64_t)handle, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId)}, interfaceHandle);
198     if (ret != HDF_SUCCESS) {
199         HDF_LOGE("%{public}s hash failed %{public}d", __func__, ret);
200     }
201     return ret;
202 }
ReleaseInterface(uint64_t interfaceHandle)203 int32_t UsbDdkService::ReleaseInterface(uint64_t interfaceHandle)
204 {
205     return ReleaseUsbInterface(interfaceHandle);
206 }
207 
SelectInterfaceSetting(uint64_t interfaceHandle,uint8_t settingIndex)208 int32_t UsbDdkService::SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex)
209 {
210     uint64_t handle = 0;
211     int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
212     if (ret != HDF_SUCCESS) {
213         HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
214         return ret;
215     }
216 
217     struct UsbInterface *interface = nullptr;
218     const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
219     return UsbSelectInterfaceSetting(handleConvert, settingIndex, &interface);
220 }
221 
GetCurrentInterfaceSetting(uint64_t interfaceHandle,uint8_t & settingIndex)222 int32_t UsbDdkService::GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t &settingIndex)
223 {
224     uint64_t handle = 0;
225     int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
226     if (ret != HDF_SUCCESS) {
227         HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
228         return ret;
229     }
230 
231     const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
232     return UsbGetInterfaceSetting(handleConvert, &settingIndex);
233 }
234 
SendControlReadRequest(uint64_t interfaceHandle,const UsbControlRequestSetup & setup,uint32_t timeout,std::vector<uint8_t> & data)235 int32_t UsbDdkService::SendControlReadRequest(
236     uint64_t interfaceHandle, const UsbControlRequestSetup &setup, uint32_t timeout, std::vector<uint8_t> &data)
237 {
238     uint64_t handle = 0;
239     int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
240     if (ret != HDF_SUCCESS) {
241         HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
242         return ret;
243     }
244 
245     const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
246     struct UsbRequest *request = UsbAllocRequest(handleConvert, 0, MAX_CONTROL_BUFF_SIZE);
247     if (request == nullptr) {
248         HDF_LOGE("%{public}s alloc request failed", __func__);
249         return HDF_DEV_ERR_NO_MEMORY;
250     }
251 
252     struct UsbRequestParams params;
253     (void)memset_s(&params, sizeof(struct UsbRequestParams), 0, sizeof(struct UsbRequestParams));
254     params.interfaceId = USB_CTRL_INTERFACE_ID;
255     params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
256     params.timeout = timeout;
257     params.ctrlReq.target = static_cast<UsbRequestTargetType>(GET_CTRL_REQ_RECIP(setup.requestType));
258     params.ctrlReq.reqType = static_cast<UsbControlRequestType>(GET_CTRL_REQ_TYPE(setup.requestType));
259     params.ctrlReq.directon = static_cast<UsbRequestDirection>(GET_CTRL_REQ_DIR(setup.requestType));
260     params.ctrlReq.request = setup.requestCmd;
261     params.ctrlReq.value = setup.value;
262     params.ctrlReq.index = setup.index;
263     params.ctrlReq.length = MAX_CONTROL_BUFF_SIZE;
264 
265     ret = UsbFillRequest(request, handleConvert, &params);
266     if (ret != HDF_SUCCESS) {
267         HDF_LOGE("%{public}s fill request failed %{public}d", __func__, ret);
268         goto FINISHED;
269     }
270 
271     ret = UsbSubmitRequestSync(request);
272     if (ret != HDF_SUCCESS) {
273         HDF_LOGE("%{public}s submit request failed %{public}d", __func__, ret);
274         goto FINISHED;
275     }
276 
277     data.assign(request->compInfo.buffer, request->compInfo.buffer + request->compInfo.actualLength);
278 FINISHED:
279     (void)UsbFreeRequest(request);
280     return ret;
281 }
282 
SendControlWriteRequest(uint64_t interfaceHandle,const UsbControlRequestSetup & setup,uint32_t timeout,const std::vector<uint8_t> & data)283 int32_t UsbDdkService::SendControlWriteRequest(
284     uint64_t interfaceHandle, const UsbControlRequestSetup &setup, uint32_t timeout, const std::vector<uint8_t> &data)
285 {
286     uint64_t handle = 0;
287     int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
288     if (ret != HDF_SUCCESS) {
289         HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
290         return ret;
291     }
292 
293     const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
294     struct UsbRequest *request = UsbAllocRequest(handleConvert, 0, MAX_CONTROL_BUFF_SIZE);
295     if (request == nullptr) {
296         HDF_LOGE("%{public}s alloc request failed", __func__);
297         return HDF_DEV_ERR_NO_MEMORY;
298     }
299 
300     struct UsbRequestParams params;
301     (void)memset_s(&params, sizeof(struct UsbRequestParams), 0, sizeof(struct UsbRequestParams));
302     params.interfaceId = USB_CTRL_INTERFACE_ID;
303     params.pipeAddress = 0;
304     params.pipeId = 0;
305     params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
306     params.timeout = timeout;
307     params.ctrlReq.target = static_cast<UsbRequestTargetType>(GET_CTRL_REQ_RECIP(setup.requestType));
308     params.ctrlReq.reqType = static_cast<UsbControlRequestType>(GET_CTRL_REQ_TYPE(setup.requestType));
309     params.ctrlReq.directon = static_cast<UsbRequestDirection>(GET_CTRL_REQ_DIR(setup.requestType));
310     params.ctrlReq.request = setup.requestCmd;
311     params.ctrlReq.value = setup.value;
312     params.ctrlReq.index = setup.index;
313     params.ctrlReq.buffer = (void *)data.data();
314     params.ctrlReq.length = data.size();
315 
316     ret = UsbFillRequest(request, handleConvert, &params);
317     if (ret != HDF_SUCCESS) {
318         HDF_LOGE("%{public}s fill request failed %{public}d", __func__, ret);
319         goto FINISHED;
320     }
321 
322     ret = UsbSubmitRequestSync(request);
323     if (ret != HDF_SUCCESS) {
324         HDF_LOGE("%{public}s submit request failed %{public}d", __func__, ret);
325         goto FINISHED;
326     }
327 
328 FINISHED:
329     (void)UsbFreeRequest(request);
330     return ret;
331 }
332 
SendPipeRequest(const UsbRequestPipe & pipe,uint32_t size,uint32_t offset,uint32_t length,uint32_t & transferedLength)333 int32_t UsbDdkService::SendPipeRequest(
334     const UsbRequestPipe &pipe, uint32_t size, uint32_t offset, uint32_t length, uint32_t &transferedLength)
335 {
336     uint64_t handle = 0;
337     int32_t ret = UsbDdkUnHash(pipe.interfaceHandle, handle);
338     if (ret != HDF_SUCCESS) {
339         HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
340         return ret;
341     }
342 
343     const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
344     struct UsbRequest *request = UsbAllocRequestByMmap(handleConvert, 0, size);
345     if (request == nullptr) {
346         HDF_LOGE("%{public}s alloc request failed", __func__);
347         return HDF_DEV_ERR_NO_MEMORY;
348     }
349 
350     struct UsbRequestParams params;
351     (void)memset_s(&params, sizeof(struct UsbRequestParams), 0, sizeof(struct UsbRequestParams));
352     params.pipeId = pipe.endpoint;
353     params.pipeAddress = pipe.endpoint;
354     params.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
355     params.timeout = pipe.timeout;
356     params.dataReq.length = length;
357 
358     ret = UsbFillRequestByMmap(request, handleConvert, &params);
359     if (ret != HDF_SUCCESS) {
360         HDF_LOGE("%{public}s fill request failed %{public}d", __func__, ret);
361         goto FINISHED;
362     }
363 
364     ret = UsbSubmitRequestSync(request);
365     if (ret != HDF_SUCCESS) {
366         HDF_LOGE("%{public}s submit request failed %{public}d", __func__, ret);
367         goto FINISHED;
368     }
369 
370     transferedLength = request->compInfo.actualLength;
371 FINISHED:
372     (void)UsbFreeRequestByMmap(request);
373     return ret;
374 }
375 
GetDeviceMemMapFd(uint64_t deviceId,int & fd)376 int32_t UsbDdkService::GetDeviceMemMapFd(uint64_t deviceId, int &fd)
377 {
378     int32_t ret = UsbGetDeviceMemMapFd(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId));
379     if (ret < 0) {
380         HDF_LOGE("%{public}s UsbGetDeviceMemMapFd failed %{public}d", __func__, ret);
381         return ret;
382     }
383     fd = ret;
384     HDF_LOGI("%{public}s:%{public}d fd:%{public}d", __func__, __LINE__, fd);
385     return HDF_SUCCESS;
386 }
387 } // namespace V1_0
388 } // namespace Ddk
389 } // namespace Usb
390 } // namespace HDI
391 } // namespace OHOS
392