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_ddk_permission.h"
25#include "usb_raw_api.h"
26#include "usbd_wrapper.h"
27#define HDF_LOG_TAG usb_ddk_service
28
29namespace OHOS {
30namespace HDI {
31namespace Usb {
32namespace Ddk {
33namespace V1_0 {
34// 32 means size of uint32_t
35#define GET_BUS_NUM(devHandle)          ((uint8_t)((devHandle) >> 32))
36#define GET_DEV_NUM(devHandle)          ((uint8_t)((devHandle)&0xFFFFFFFF))
37#define USB_RECIP_MASK                  0x1F
38#define GET_CTRL_REQ_RECIP(requestType) ((requestType)&USB_RECIP_MASK)
39#define TRANS_DIRECTION_OFFSET          7
40#define GET_CTRL_REQ_DIR(requestType)   ((requestType) >> TRANS_DIRECTION_OFFSET)
41#define REQ_TYPE_OFFERT                 5
42#define REQ_TYPE_MASK                   0x3
43#define GET_CTRL_REQ_TYPE(requestType)  (((requestType) >> REQ_TYPE_OFFERT) & REQ_TYPE_MASK)
44
45#define MAX_BUFF_SIZE         16384
46#define MAX_CONTROL_BUFF_SIZE 1024
47
48static const std::string PERMISSION_NAME = "ohos.permission.ACCESS_DDK_USB";
49static std::mutex g_infMutex;
50extern "C" IUsbDdk *UsbDdkImplGetInstance(void)
51{
52    return new (std::nothrow) UsbDdkService();
53}
54
55int32_t ReleaseUsbInterface(uint64_t interfaceHandle)
56{
57    std::lock_guard<std::mutex> lock(g_infMutex);
58    uint64_t handle = 0;
59    int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
60    if (ret != HDF_SUCCESS) {
61        HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
62        return ret;
63    }
64    UsbDdkDelHashRecord(interfaceHandle);
65
66    struct UsbInterface *interface = nullptr;
67    const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
68    ret = GetInterfaceByHandle(handleConvert, &interface);
69    if (ret != HDF_SUCCESS) {
70        HDF_LOGE("%{public}s get interface failed %{public}d", __func__, ret);
71        return ret;
72    }
73
74    ret = UsbCloseInterface(handleConvert, false);
75    if (ret != HDF_SUCCESS) {
76        HDF_LOGE("%{public}s close interface failed %{public}d", __func__, ret);
77        return ret;
78    }
79
80    return UsbReleaseInterface(interface);
81}
82
83static int32_t UsbdPnpEventHandler(void *priv, uint32_t id, HdfSBuf *data)
84{
85    if (id == USB_PNP_NOTIFY_REMOVE_DEVICE) {
86        uint32_t infoSize;
87        struct UsbPnpNotifyMatchInfoTable *infoTable = NULL;
88        auto flag = HdfSbufReadBuffer(data, (const void **)(&infoTable), &infoSize);
89        if ((!flag) || (infoTable == NULL)) {
90            HDF_LOGE("%{public}s: fail to read infoTable in event data, flag = %{public}d", __func__, flag);
91            return HDF_ERR_INVALID_PARAM;
92        }
93
94        uint64_t interfaceHandle = 0;
95        if (UsbDdkGetRecordByVal({0, infoTable->busNum, infoTable->devNum}, interfaceHandle)) {
96            HDF_LOGD("%{public}s: need release interface", __func__);
97            ReleaseUsbInterface(interfaceHandle);
98        }
99    }
100    return HDF_SUCCESS;
101}
102
103static HdfDevEventlistener *g_pnpListener = nullptr;
104
105int32_t UsbDdkService::Init()
106{
107    HDF_LOGI("usb ddk init");
108    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
109        HDF_LOGE("%{public}s: no permission", __func__);
110        return HDF_ERR_NOPERM;
111    }
112    if (g_pnpListener == nullptr) {
113        g_pnpListener = new HdfDevEventlistener();
114        if (g_pnpListener == nullptr) {
115            HDF_LOGE("%{public}s: create listener failed", __func__);
116            return HDF_ERR_MALLOC_FAIL;
117        }
118        g_pnpListener->callBack = UsbdPnpEventHandler;
119        if (DdkListenerMgrAdd(g_pnpListener) != HDF_SUCCESS) {
120            HDF_LOGE("%{public}s: add listener failed", __func__);
121            delete g_pnpListener;
122            g_pnpListener = nullptr;
123            return HDF_FAILURE;
124        }
125    }
126
127    return UsbInitHostSdk(nullptr);
128}
129
130int32_t UsbDdkService::Release()
131{
132    HDF_LOGI("usb ddk exit");
133    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
134        HDF_LOGE("%{public}s: no permission", __func__);
135        return HDF_ERR_NOPERM;
136    }
137
138    DdkPermissionManager::Reset();
139    return UsbExitHostSdk(nullptr);
140}
141
142int32_t UsbDdkService::GetDeviceDescriptor(uint64_t deviceId, UsbDeviceDescriptor &desc)
143{
144    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
145        HDF_LOGE("%{public}s: no permission", __func__);
146        return HDF_ERR_NOPERM;
147    }
148
149    UsbRawHandle *rawHandle = UsbRawOpenDevice(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId));
150    if (rawHandle == nullptr) {
151        HDF_LOGE("%{public}s open device failed", __func__);
152        return HDF_FAILURE;
153    }
154
155    UsbRawDevice *rawDevice = UsbRawGetDevice(rawHandle);
156    if (rawDevice == nullptr) {
157        HDF_LOGE("%{public}s get device failed", __func__);
158        (void)UsbRawCloseDevice(rawHandle);
159        return HDF_FAILURE;
160    }
161
162    int32_t ret = UsbRawGetDeviceDescriptor(rawDevice, reinterpret_cast<::UsbDeviceDescriptor *>(&desc));
163    if (ret != HDF_SUCCESS) {
164        HDF_LOGW("%{public}s get desc failed %{public}d", __func__, ret);
165    }
166    (void)UsbRawCloseDevice(rawHandle);
167    return ret;
168}
169
170int32_t UsbDdkService::GetConfigDescriptor(uint64_t deviceId, uint8_t configIndex, std::vector<uint8_t> &configDesc)
171{
172    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
173        HDF_LOGE("%{public}s: no permission", __func__);
174        return HDF_ERR_NOPERM;
175    }
176
177    UsbRawHandle *rawHandle = UsbRawOpenDevice(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId));
178    if (rawHandle == nullptr) {
179        HDF_LOGE("%{public}s open device failed", __func__);
180        return HDF_FAILURE;
181    }
182
183    struct UsbConfigDescriptor tmpDesc {};
184    int32_t ret = GetRawConfigDescriptor(
185        rawHandle, configIndex, reinterpret_cast<uint8_t *>(&tmpDesc), sizeof(struct UsbConfigDescriptor));
186    if (ret <= 0) {
187        HDF_LOGW("%{public}s get config desc failed %{public}d", __func__, ret);
188        (void)UsbRawCloseDevice(rawHandle);
189        return ret;
190    }
191
192    std::vector<uint8_t> tmpBuffer(tmpDesc.wTotalLength);
193    ret = GetRawConfigDescriptor(rawHandle, configIndex, tmpBuffer.data(), tmpDesc.wTotalLength);
194    if (ret <= 0) {
195        HDF_LOGW("%{public}s get config desc failed %{public}d", __func__, ret);
196        (void)UsbRawCloseDevice(rawHandle);
197        return ret;
198    }
199
200    if (static_cast<size_t>(ret) != tmpBuffer.size()) {
201        HDF_LOGE("%{public}s config desc invalid length : %{public}d, bufferSize:%{public}zu", __func__, ret,
202            tmpBuffer.size());
203        return HDF_FAILURE;
204    }
205
206    configDesc = tmpBuffer;
207
208    (void)UsbRawCloseDevice(rawHandle);
209    return HDF_SUCCESS;
210}
211
212int32_t UsbDdkService::ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t &interfaceHandle)
213{
214    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
215        HDF_LOGE("%{public}s: no permission", __func__);
216        return HDF_ERR_NOPERM;
217    }
218
219    struct UsbInterface *interface =
220        UsbClaimInterface(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId), interfaceIndex);
221    if (interface == nullptr) {
222        HDF_LOGE("%{public}s claim failed", __func__);
223        return HDF_FAILURE;
224    }
225
226    UsbInterfaceHandle *handle = UsbOpenInterface(interface);
227    if (handle == nullptr) {
228        HDF_LOGE("%{public}s open failed", __func__);
229        return HDF_FAILURE;
230    }
231
232    int32_t ret = UsbDdkHash({(uint64_t)handle, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId)}, interfaceHandle);
233    if (ret != HDF_SUCCESS) {
234        HDF_LOGE("%{public}s hash failed %{public}d", __func__, ret);
235    }
236    return ret;
237}
238
239int32_t UsbDdkService::ReleaseInterface(uint64_t interfaceHandle)
240{
241    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
242        HDF_LOGE("%{public}s: no permission", __func__);
243        return HDF_ERR_NOPERM;
244    }
245
246    return ReleaseUsbInterface(interfaceHandle);
247}
248
249int32_t UsbDdkService::SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex)
250{
251    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
252        HDF_LOGE("%{public}s: no permission", __func__);
253        return HDF_ERR_NOPERM;
254    }
255
256    uint64_t handle = 0;
257    int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
258    if (ret != HDF_SUCCESS) {
259        HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
260        return ret;
261    }
262
263    struct UsbInterface *interface = nullptr;
264    const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
265    return UsbSelectInterfaceSetting(handleConvert, settingIndex, &interface);
266}
267
268int32_t UsbDdkService::GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t &settingIndex)
269{
270    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
271        HDF_LOGE("%{public}s: no permission", __func__);
272        return HDF_ERR_NOPERM;
273    }
274
275    uint64_t handle = 0;
276    int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
277    if (ret != HDF_SUCCESS) {
278        HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
279        return ret;
280    }
281
282    const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
283    return UsbGetInterfaceSetting(handleConvert, &settingIndex);
284}
285
286int32_t UsbDdkService::SendControlReadRequest(
287    uint64_t interfaceHandle, const UsbControlRequestSetup &setup, uint32_t timeout, std::vector<uint8_t> &data)
288{
289    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
290        HDF_LOGE("%{public}s: no permission", __func__);
291        return HDF_ERR_NOPERM;
292    }
293
294    uint64_t handle = 0;
295    int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
296    if (ret != HDF_SUCCESS) {
297        HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
298        return ret;
299    }
300
301    const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
302    uint32_t length = setup.length > MAX_CONTROL_BUFF_SIZE ? MAX_CONTROL_BUFF_SIZE : setup.length;
303    struct UsbRequest *request = UsbAllocRequest(handleConvert, 0, static_cast<int32_t>(length));
304    if (request == nullptr) {
305        HDF_LOGE("%{public}s alloc request failed", __func__);
306        return HDF_DEV_ERR_NO_MEMORY;
307    }
308
309    struct UsbRequestParams params;
310    (void)memset_s(&params, sizeof(struct UsbRequestParams), 0, sizeof(struct UsbRequestParams));
311    params.interfaceId = USB_CTRL_INTERFACE_ID;
312    params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
313    params.timeout = timeout;
314    params.ctrlReq.target = static_cast<UsbRequestTargetType>(GET_CTRL_REQ_RECIP(setup.requestType));
315    params.ctrlReq.reqType = setup.requestType;
316    params.ctrlReq.directon = static_cast<UsbRequestDirection>(GET_CTRL_REQ_DIR(setup.requestType));
317    params.ctrlReq.request = setup.requestCmd;
318    params.ctrlReq.value = setup.value;
319    params.ctrlReq.index = setup.index;
320    params.ctrlReq.length = length;
321
322    ret = UsbFillRequest(request, handleConvert, &params);
323    if (ret != HDF_SUCCESS) {
324        HDF_LOGE("%{public}s fill request failed %{public}d", __func__, ret);
325        goto FINISHED;
326    }
327
328    ret = UsbSubmitRequestSync(request);
329    if (ret != HDF_SUCCESS) {
330        HDF_LOGE("%{public}s submit request failed %{public}d", __func__, ret);
331        goto FINISHED;
332    }
333
334    data.assign(request->compInfo.buffer, request->compInfo.buffer + request->compInfo.actualLength);
335FINISHED:
336    (void)UsbFreeRequest(request);
337    return ret;
338}
339
340int32_t UsbDdkService::SendControlWriteRequest(
341    uint64_t interfaceHandle, const UsbControlRequestSetup &setup, uint32_t timeout, const std::vector<uint8_t> &data)
342{
343    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
344        HDF_LOGE("%{public}s: no permission", __func__);
345        return HDF_ERR_NOPERM;
346    }
347
348    uint64_t handle = 0;
349    int32_t ret = UsbDdkUnHash(interfaceHandle, handle);
350    if (ret != HDF_SUCCESS) {
351        HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
352        return ret;
353    }
354
355    const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
356    struct UsbRequest *request = UsbAllocRequest(handleConvert, 0, MAX_CONTROL_BUFF_SIZE);
357    if (request == nullptr) {
358        HDF_LOGE("%{public}s alloc request failed", __func__);
359        return HDF_DEV_ERR_NO_MEMORY;
360    }
361
362    struct UsbRequestParams params;
363    (void)memset_s(&params, sizeof(struct UsbRequestParams), 0, sizeof(struct UsbRequestParams));
364    params.interfaceId = USB_CTRL_INTERFACE_ID;
365    params.pipeAddress = 0;
366    params.pipeId = 0;
367    params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
368    params.timeout = timeout;
369    params.ctrlReq.target = static_cast<UsbRequestTargetType>(GET_CTRL_REQ_RECIP(setup.requestType));
370    params.ctrlReq.reqType = setup.requestType;
371    params.ctrlReq.directon = static_cast<UsbRequestDirection>(GET_CTRL_REQ_DIR(setup.requestType));
372    params.ctrlReq.request = setup.requestCmd;
373    params.ctrlReq.value = setup.value;
374    params.ctrlReq.index = setup.index;
375    params.ctrlReq.buffer = (void *)data.data();
376    params.ctrlReq.length = data.size();
377
378    ret = UsbFillRequest(request, handleConvert, &params);
379    if (ret != HDF_SUCCESS) {
380        HDF_LOGE("%{public}s fill request failed %{public}d", __func__, ret);
381        goto FINISHED;
382    }
383
384    ret = UsbSubmitRequestSync(request);
385    if (ret != HDF_SUCCESS) {
386        HDF_LOGE("%{public}s submit request failed %{public}d", __func__, ret);
387        goto FINISHED;
388    }
389
390FINISHED:
391    (void)UsbFreeRequest(request);
392    return ret;
393}
394
395int32_t UsbDdkService::SendPipeRequest(
396    const UsbRequestPipe &pipe, uint32_t size, uint32_t offset, uint32_t length, uint32_t &transferedLength)
397{
398    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
399        HDF_LOGE("%{public}s: no permission", __func__);
400        return HDF_ERR_NOPERM;
401    }
402
403    std::lock_guard<std::mutex> lock(g_infMutex);
404    uint64_t handle = 0;
405    int32_t ret = UsbDdkUnHash(pipe.interfaceHandle, handle);
406    if (ret != HDF_SUCCESS) {
407        HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
408        return ret;
409    }
410
411    const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
412    struct UsbRequest *request = UsbAllocRequestByMmap(handleConvert, 0, size);
413    if (request == nullptr) {
414        HDF_LOGE("%{public}s alloc request failed", __func__);
415        return HDF_DEV_ERR_NO_MEMORY;
416    }
417
418    struct UsbRequestParams params;
419    (void)memset_s(&params, sizeof(struct UsbRequestParams), 0, sizeof(struct UsbRequestParams));
420    params.pipeId = pipe.endpoint;
421    params.pipeAddress = pipe.endpoint;
422    params.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
423    params.timeout = pipe.timeout;
424    params.dataReq.length = length;
425
426    ret = UsbFillRequestByMmap(request, handleConvert, &params);
427    if (ret != HDF_SUCCESS) {
428        HDF_LOGE("%{public}s fill request failed %{public}d", __func__, ret);
429        goto FINISHED;
430    }
431
432    ret = UsbSubmitRequestSync(request);
433    if (ret != HDF_SUCCESS) {
434        HDF_LOGE("%{public}s submit request failed %{public}d", __func__, ret);
435        goto FINISHED;
436    }
437
438    transferedLength = request->compInfo.actualLength;
439FINISHED:
440    (void)UsbFreeRequestByMmap(request);
441    return ret;
442}
443
444int32_t UsbDdkService::SendPipeRequestWithAshmem(
445    const UsbRequestPipe &pipe, const UsbAshmem &ashmem, uint32_t &transferredLength)
446{
447    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
448        HDF_LOGE("%{public}s: no permission", __func__);
449        return HDF_ERR_NOPERM;
450    }
451
452    std::lock_guard<std::mutex> lock(g_infMutex);
453    uint64_t handle = 0;
454    int32_t ret = UsbDdkUnHash(pipe.interfaceHandle, handle);
455    if (ret != HDF_SUCCESS) {
456        HDF_LOGE("%{public}s unhash failed %{public}d", __func__, ret);
457        return ret;
458    }
459
460    const UsbInterfaceHandle *handleConvert = reinterpret_cast<const UsbInterfaceHandle *>(handle);
461    struct UsbRequest *request = UsbAllocRequestByAshmem(handleConvert, 0, ashmem.size, ashmem.ashmemFd);
462    if (request == nullptr) {
463        HDF_LOGE("%{public}s alloc request failed", __func__);
464        return HDF_DEV_ERR_NO_MEMORY;
465    }
466
467    struct UsbRequestParams params;
468    (void)memset_s(&params, sizeof(struct UsbRequestParams), 0, sizeof(struct UsbRequestParams));
469    params.pipeId = pipe.endpoint;
470    params.pipeAddress = pipe.endpoint;
471    params.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
472    params.timeout = pipe.timeout;
473    params.dataReq.length = ashmem.bufferLength;
474
475    ret = UsbFillRequestByMmap(request, handleConvert, &params);
476    if (ret != HDF_SUCCESS) {
477        HDF_LOGE("%{public}s fill request failed %{public}d", __func__, ret);
478        goto FINISHED;
479    }
480
481    ret = UsbSubmitRequestSync(request);
482    if (ret != HDF_SUCCESS) {
483        HDF_LOGE("%{public}s submit request failed %{public}d", __func__, ret);
484        goto FINISHED;
485    }
486
487    transferredLength = request->compInfo.actualLength;
488FINISHED:
489    (void)UsbFreeRequestByMmap(request);
490    return ret;
491}
492
493int32_t UsbDdkService::GetDeviceMemMapFd(uint64_t deviceId, int &fd)
494{
495    if (!DdkPermissionManager::VerifyPermission(PERMISSION_NAME)) {
496        HDF_LOGE("%{public}s: no permission", __func__);
497        return HDF_ERR_NOPERM;
498    }
499
500    int32_t ret = UsbGetDeviceMemMapFd(nullptr, GET_BUS_NUM(deviceId), GET_DEV_NUM(deviceId));
501    if (ret < 0) {
502        HDF_LOGE("%{public}s UsbGetDeviceMemMapFd failed %{public}d", __func__, ret);
503        return ret;
504    }
505    fd = ret;
506    HDF_LOGI("%{public}s:%{public}d fd:%{public}d", __func__, __LINE__, fd);
507    return HDF_SUCCESS;
508}
509} // namespace V1_0
510} // namespace Ddk
511} // namespace Usb
512} // namespace HDI
513} // namespace OHOS
514