1/*
2 * Copyright (c) 2022-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 "usbd_dispatcher.h"
17#include "hdf_slist.h"
18#include "osal_mutex.h"
19#include "usb_ddk.h"
20#include "usb_impl.h"
21#include "usb_interface_pool.h"
22#include "v1_0/iusbd_subscriber.h"
23#include "usbd_wrapper.h"
24
25namespace OHOS {
26namespace HDI {
27namespace Usb {
28namespace V1_1 {
29int32_t UsbdDispatcher::UsbdAllocFifo(DataFifo *fifo, uint32_t size)
30{
31    if (!DataFifoIsInitialized(fifo)) {
32        void *data = OsalMemAlloc(size);
33        if (data == nullptr) {
34            HDF_LOGE("%{public}s:OsalMemAlloc failed", __func__);
35            return HDF_ERR_MALLOC_FAIL;
36        }
37        DataFifoInit(fifo, size, data);
38    }
39    return HDF_SUCCESS;
40}
41
42void UsbdDispatcher::UsbdFreeFifo(DataFifo *fifo)
43{
44    if (fifo == nullptr) {
45        HDF_LOGE("%{public}s:fifo is nullptr", __func__);
46        return;
47    }
48
49    OsalMemFree(fifo->data);
50    fifo->data = nullptr;
51    DataFifoInit(fifo, 0, nullptr);
52}
53
54void UsbdDispatcher::UsbdReadCallback(UsbRequest *req)
55{
56    if (req == nullptr) {
57        HDF_LOGE("%{public}s:req is nullptr!", __func__);
58        return;
59    }
60
61    UsbIfRequest *reqObj = reinterpret_cast<UsbIfRequest *>(req);
62    UsbdRequestASync *dev = static_cast<UsbdRequestASync *>(req->compInfo.userData);
63    if (dev == nullptr) {
64        HDF_LOGE("%{public}s:invalid param dev is nullptr!", __func__);
65        OsalSemPost(&reqObj->hostRequest->sem);
66    }
67}
68
69void UsbdDispatcher::UsbdWriteCallback(UsbRequest *req)
70{
71    if (req == nullptr) {
72        HDF_LOGE("%{public}s:invalid param req is nullptr!", __func__);
73        return;
74    }
75
76    int32_t status = req->compInfo.status;
77    HDF_LOGI("%{public}s:status is %{public}d!", __func__, status);
78}
79
80int32_t UsbdDispatcher::UsbControlSetUp(UsbControlParams *controlParams, UsbControlRequest *controlReq)
81{
82    if (controlParams == nullptr || controlReq == nullptr) {
83        HDF_LOGE("%{public}s:controlParams or controlReq is nullptr", __func__);
84        return HDF_ERR_INVALID_PARAM;
85    }
86
87    controlReq->target = controlParams->target;
88    controlReq->reqType = controlParams->reqType;
89    controlReq->directon = controlParams->directon;
90    controlReq->request = controlParams->request;
91    controlReq->value = controlParams->value;
92    controlReq->index = controlParams->index;
93    controlReq->buffer = controlParams->data;
94    controlReq->length = static_cast<uint32_t>(controlParams->size);
95    return HDF_SUCCESS;
96}
97
98UsbInterface *UsbdDispatcher::GetUsbInterfaceById(const HostDevice *dev, uint8_t interfaceIndex)
99{
100    if (dev == nullptr || dev->service == nullptr) {
101        HDF_LOGE("%{public}s:idx:%{public}u service is nullptr", __func__, interfaceIndex);
102        return nullptr;
103    }
104
105    UsbInterface *tmpIf = UsbClaimInterface(dev->service->session_, dev->busNum, dev->devAddr, interfaceIndex);
106    if (tmpIf == nullptr) {
107        HDF_LOGE("%{public}s: UsbClaimInterface failed", __func__);
108    }
109    return tmpIf;
110}
111
112int32_t UsbdDispatcher::GetInterfacePipe(
113    const HostDevice *dev, UsbInterface *interface, uint8_t pipeAddr, UsbPipeInfo *pipe)
114{
115    UsbPipeInfo pipeTmp;
116    if (memset_s(&pipeTmp, sizeof(pipeTmp), 0, sizeof(pipeTmp)) != EOK) {
117        HDF_LOGE("%{public}s:memset_s failed ", __func__);
118        return HDF_FAILURE;
119    }
120
121    if (dev == nullptr || interface == nullptr || pipe == nullptr) {
122        HDF_LOGE("%{public}s:invalid params", __func__);
123        return HDF_ERR_INVALID_PARAM;
124    }
125
126    UsbInterfaceInfo *info = &interface->info;
127    if (info == nullptr) {
128        HDF_LOGE("%{public}s:invalid interface", __func__);
129        return HDF_FAILURE;
130    }
131
132    UsbInterfaceHandle *interfaceHandle = UsbImpl::InterfaceIdToHandle(dev, info->interfaceIndex);
133    if (interfaceHandle == nullptr) {
134        HDF_LOGE("%{public}s:invalid interface handle", __func__);
135        return HDF_FAILURE;
136    }
137
138    int32_t ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, pipeAddr, &pipeTmp);
139    if (ret == HDF_SUCCESS && ((pipeTmp.pipeAddress | static_cast<uint8_t>(pipeTmp.pipeDirection)) == pipeAddr)) {
140        if (pipe) {
141            *pipe = pipeTmp;
142        }
143        return HDF_SUCCESS;
144    }
145    return HDF_FAILURE;
146}
147
148int32_t UsbdDispatcher::GetPipe(const HostDevice *dev, uint8_t interfaceId, uint8_t pipeId, UsbPipeInfo *pipe)
149{
150    if (dev == nullptr || pipe == nullptr) {
151        HDF_LOGE("%{public}s:dev or pipe is nullptr, ifId:%{public}u epId:%{public}u", __func__, interfaceId, pipeId);
152        return HDF_ERR_INVALID_PARAM;
153    }
154
155    if (interfaceId >= USB_MAX_INTERFACES) {
156        HDF_LOGE("%{public}s:interfaceId invalid, ifId:%{public}u epId:%{public}u", __func__, interfaceId, pipeId);
157        return HDF_ERR_INVALID_PARAM;
158    }
159
160    UsbInterface *interface = dev->iface[interfaceId];
161    if (interface == nullptr) {
162        HDF_LOGE("%{public}s:interface is nullptr ifId:%{public}u, epId:%{public}u", __func__, interfaceId, pipeId);
163        return HDF_FAILURE;
164    }
165
166    int32_t ret = GetInterfacePipe(dev, interface, pipeId, pipe);
167    return ret;
168}
169
170void UsbdDispatcher::UsbdFreeCtrlPipe(HostDevice *dev)
171{
172    if (dev == nullptr) {
173        HDF_LOGE("%{public}s:params dev is nullptr", __func__);
174        return;
175    }
176
177    OsalMemFree(dev->ctrPipe);
178    dev->ctrPipe = nullptr;
179}
180
181int32_t UsbdDispatcher::UsbdGetCtrlPipe(HostDevice *dev)
182{
183    UsbPipeInfo *pipe = static_cast<UsbPipeInfo *>(OsalMemCalloc(sizeof(UsbPipeInfo)));
184    if (pipe == nullptr) {
185        HDF_LOGE("%{public}s:OsalMemCalloc failed", __func__);
186        return HDF_ERR_MALLOC_FAIL;
187    }
188
189    int32_t ret = UsbGetPipeInfo(dev->ctrDevHandle, dev->ctrIface->info.curAltSetting, 0, pipe);
190    if (ret != HDF_SUCCESS) {
191        HDF_LOGE("%{public}s:get pipe failed ret:%{public}d", __func__, ret);
192        OsalMemFree(pipe);
193        pipe = nullptr;
194        return HDF_FAILURE;
195    }
196
197    dev->ctrPipe = pipe;
198    return HDF_SUCCESS;
199}
200
201UsbdRequestSync *UsbdDispatcher::UsbdFindRequestSync(HostDevice *port, uint8_t interfaceId, uint8_t pipeAddr)
202{
203    if (port == nullptr) {
204        HDF_LOGE("%{public}s:invalid param port is nullptr", __func__);
205        return nullptr;
206    }
207
208    UsbdRequestSync *req = nullptr;
209    HdfSListIterator it;
210    bool flag = false;
211    OsalMutexLock(&port->reqSyncLock);
212    HdfSListIteratorInit(&it, &port->reqSyncList);
213    while (HdfSListIteratorHasNext(&it)) {
214        req = reinterpret_cast<UsbdRequestSync *>(HdfSListIteratorNext(&it));
215        if (req == nullptr) {
216            continue;
217        }
218        if (req->pipe.interfaceId == interfaceId && ((req->pipe.pipeAddress | req->pipe.pipeDirection) == pipeAddr)) {
219            flag = true;
220            break;
221        }
222    }
223    OsalMutexUnlock(&port->reqSyncLock);
224
225    if (flag) {
226        return req;
227    }
228    return nullptr;
229}
230
231UsbdRequestSync *UsbdDispatcher::UsbdRequestSyncAlloc(void)
232{
233    UsbdRequestSync *req = static_cast<UsbdRequestSync *>(OsalMemCalloc(sizeof(UsbdRequestSync)));
234    if (req == nullptr) {
235        HDF_LOGE("%{public}s: OsalMemCalloc failed", __func__);
236        return req;
237    }
238
239    req->request = nullptr;
240    req->endPointAddr = 0;
241    req->ifHandle = nullptr;
242    OsalMutexInit(&req->lock);
243    return req;
244}
245
246void UsbdDispatcher::UsbRequestParamsWSyncInit(UsbRequestParams *params, int32_t timeout, const UsbPipeInfo *pipe)
247{
248    if (params == nullptr || pipe == nullptr) {
249        HDF_LOGE("%{public}s: params or pipe is nullptr", __func__);
250        return;
251    }
252
253    params->interfaceId = pipe->interfaceId;
254    params->pipeAddress = pipe->pipeDirection | pipe->pipeAddress;
255    params->pipeId = pipe->pipeId;
256    params->requestType = USB_REQUEST_PARAMS_DATA_TYPE;
257    params->timeout = static_cast<uint32_t>(timeout);
258    params->dataReq.numIsoPackets = 0;
259    params->dataReq.directon = static_cast<UsbRequestDirection>((pipe->pipeDirection >> USB_DIR_OFFSET) & 0x1);
260    params->dataReq.length = pipe->maxPacketSize;
261}
262
263int32_t UsbdDispatcher::UsbdRequestSyncInit(
264    HostDevice *port, UsbInterfaceHandle *ifHandle, UsbPipeInfo *pipe, UsbdRequestSync *requestSync)
265{
266    if (port == nullptr || requestSync == nullptr || ifHandle == nullptr || pipe == nullptr) {
267        HDF_LOGE("%{public}s:invalid params", __func__);
268        return HDF_ERR_INVALID_PARAM;
269    }
270
271    int32_t ret = memcpy_s(&requestSync->pipe, sizeof(UsbPipeInfo), pipe, sizeof(UsbPipeInfo));
272    if (ret != EOK) {
273        HDF_LOGE("%{public}s:%{public}d memcpy_s failed", __func__, ret);
274        return ret;
275    }
276
277    requestSync->ifHandle = ifHandle;
278    requestSync->request = UsbAllocRequest(requestSync->ifHandle, 0, requestSync->pipe.maxPacketSize);
279    if (requestSync->request == nullptr) {
280        HDF_LOGE("%{public}s:alloc request failed", __func__);
281        return HDF_ERR_MALLOC_FAIL;
282    }
283    UsbRequestParamsWSyncInit(&requestSync->params, USB_CTRL_SET_TIMEOUT, &requestSync->pipe);
284    requestSync->params.userData = port;
285    OsalMutexLock(&port->reqSyncLock);
286    HdfSListAdd(&port->reqSyncList, &requestSync->node);
287    OsalMutexUnlock(&port->reqSyncLock);
288    return HDF_SUCCESS;
289}
290
291int32_t UsbdDispatcher::UsbdRequestSyncInitwithLength(HostDevice *port, UsbInterfaceHandle *ifHandle,
292    UsbPipeInfo *pipe, int32_t length, UsbdRequestSync *requestSync)
293{
294    if (port == nullptr || requestSync == nullptr || ifHandle == nullptr || pipe == nullptr) {
295        HDF_LOGE("%{public}s:invalid params", __func__);
296        return HDF_ERR_INVALID_PARAM;
297    }
298
299    int32_t ret = memcpy_s(&requestSync->pipe, sizeof(UsbPipeInfo), pipe, sizeof(UsbPipeInfo));
300    if (ret != EOK) {
301        HDF_LOGE("%{public}s:%{public}d memcpy_s failed", __func__, ret);
302        return ret;
303    }
304
305    requestSync->ifHandle = ifHandle;
306    requestSync->request = UsbAllocRequest(requestSync->ifHandle, 0, length);
307    if (requestSync->request == nullptr) {
308        HDF_LOGE("%{public}s:alloc request failed", __func__);
309        return HDF_ERR_MALLOC_FAIL;
310    }
311    UsbRequestParamsWSyncInit(&requestSync->params, USB_CTRL_SET_TIMEOUT, &requestSync->pipe);
312    requestSync->params.userData = port;
313    OsalMutexLock(&port->reqSyncLock);
314    HdfSListAdd(&port->reqSyncList, &requestSync->node);
315    OsalMutexUnlock(&port->reqSyncLock);
316    return HDF_SUCCESS;
317}
318
319int32_t UsbdDispatcher::UsbdRequestSyncRelease(UsbdRequestSync *requestSync)
320{
321    int32_t ret = HDF_SUCCESS;
322    if (requestSync != nullptr) {
323        OsalMutexLock(&requestSync->lock);
324        if (requestSync->request != nullptr) {
325            ret = UsbFreeRequest(requestSync->request);
326            if (ret != HDF_SUCCESS) {
327                HDF_LOGW("%{public}s:UsbFreeRequest failed", __func__);
328            }
329            requestSync->request = nullptr;
330        }
331        OsalMutexUnlock(&requestSync->lock);
332        OsalMemFree(requestSync);
333    }
334    return ret;
335}
336
337void UsbdDispatcher::UsbRequestParamsInit(UsbRequestParams *params, int32_t timeout)
338{
339    if (params == nullptr) {
340        HDF_LOGE("%{public}s:params is nullptr", __func__);
341        return;
342    }
343
344    params->interfaceId = USB_CTRL_INTERFACE_ID;
345    params->pipeAddress = 0;
346    params->pipeId = 0;
347    params->requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
348    params->timeout = static_cast<uint32_t>(timeout);
349}
350
351int32_t UsbdDispatcher::CtrlTranParamGetReqType(HdfSBuf *data, UsbControlParams *pCtrParams, uint32_t requestType)
352{
353    if (data == nullptr || pCtrParams == nullptr) {
354        HDF_LOGE("%{public}s:param failed", __func__);
355        return HDF_ERR_INVALID_PARAM;
356    }
357
358    uint8_t *buffer = nullptr;
359    uint32_t length = 0;
360    int32_t target = requestType & USB_RECIP_MASK;
361    int32_t direction = (requestType >> DIRECTION_OFFSET_7) & ENDPOINT_DIRECTION_MASK;
362    int32_t cmdType = (requestType >> CMD_OFFSET_5) & CMD_TYPE_MASK;
363    if (direction == USB_REQUEST_DIR_TO_DEVICE) {
364        if (!HdfSbufReadBuffer(data, (const void **)(&buffer), &length)) {
365            HDF_LOGE("%{public}s:hdf sbuf Read failed", __func__);
366            return HDF_FAILURE;
367        }
368    } else {
369        length = MAX_CONTROL_BUFF_SIZE;
370        buffer = static_cast<uint8_t *>(OsalMemCalloc(length));
371        if (buffer == nullptr) {
372            HDF_LOGE("%{public}s:OsalMemCalloc failed length = %{public}u", __func__, length);
373            return HDF_ERR_MALLOC_FAIL;
374        }
375    }
376    pCtrParams->target = static_cast<UsbRequestTargetType>(target);
377    pCtrParams->directon = static_cast<UsbRequestDirection>(direction);
378    pCtrParams->reqType = static_cast<UsbControlRequestType>(cmdType);
379    pCtrParams->size = length;
380    pCtrParams->data = buffer;
381    return HDF_SUCCESS;
382}
383
384int32_t UsbdDispatcher::CtrlTransferParamInit(HdfSBuf *data, UsbControlParams *pCtrParams, int32_t *timeout)
385{
386    if (data == nullptr || pCtrParams == nullptr) {
387        HDF_LOGE("%{public}s:data or pCtrParams is nullptr", __func__);
388        return HDF_ERR_INVALID_PARAM;
389    }
390
391    int32_t requestType;
392    if (!HdfSbufReadInt32(data, &requestType)) {
393        HDF_LOGE("%{public}s:failed to read the requestType from data", __func__);
394        return HDF_ERR_IO;
395    }
396
397    int32_t requestCmd;
398    if (!HdfSbufReadInt32(data, &requestCmd)) {
399        HDF_LOGE("%{public}s:Failed to read the requestCmd from data", __func__);
400        return HDF_ERR_IO;
401    }
402
403    int32_t value;
404    if (!HdfSbufReadInt32(data, &value)) {
405        HDF_LOGE("%{public}s:Failed to read the value from data", __func__);
406        return HDF_ERR_IO;
407    }
408
409    int32_t index;
410    if (!HdfSbufReadInt32(data, &index)) {
411        HDF_LOGE("%{public}s:Failed to read the index from data", __func__);
412        return HDF_ERR_IO;
413    }
414
415    if (!HdfSbufReadInt32(data, timeout)) {
416        HDF_LOGE("%{public}s:Failed to read the timeout from data", __func__);
417        return HDF_ERR_IO;
418    }
419
420    pCtrParams->request = static_cast<uint8_t>(requestCmd);
421    pCtrParams->value = value;
422    pCtrParams->index = index;
423    int32_t ret = CtrlTranParamGetReqType(data, pCtrParams, requestType);
424    if (ret != HDF_SUCCESS) {
425        HDF_LOGE("%{public}s:CtrlTransferParamInit failed:%{public}d", __func__, ret);
426        OsalMemFree(pCtrParams->data);
427        pCtrParams->data = nullptr;
428    }
429    return ret;
430}
431
432void UsbdDispatcher::UsbdReleaseInterfaces(HostDevice *dev)
433{
434    if (dev == nullptr) {
435        HDF_LOGE("%{public}s: %{public}d invalid param dev is nullptr", __func__, __LINE__);
436        return;
437    }
438
439    for (int32_t i = 0; i < USB_MAX_INTERFACES; ++i) {
440        if (dev->iface[i] != nullptr) {
441            UsbReleaseInterface(dev->iface[i]);
442            dev->iface[i] = nullptr;
443        }
444    }
445    if (dev->ctrIface != nullptr) {
446        UsbReleaseInterface(dev->ctrIface);
447        dev->ctrIface = nullptr;
448    }
449}
450
451void UsbdDispatcher::UsbdCloseInterfaces(HostDevice *dev)
452{
453    if (dev == nullptr) {
454        HDF_LOGE("%{public}s: %{public}d invalid param dev is nullptr", __func__, __LINE__);
455        return;
456    }
457
458    for (int32_t i = 0; i < USB_MAX_INTERFACES; ++i) {
459        if (dev->devHandle[i] != nullptr) {
460            UsbCloseInterface(dev->devHandle[i], false);
461            dev->devHandle[i] = nullptr;
462        }
463    }
464    if (dev->ctrDevHandle != nullptr) {
465        UsbCloseInterface(dev->ctrDevHandle, false);
466        dev->ctrDevHandle = nullptr;
467    }
468}
469
470int32_t UsbdDispatcher::UsbdOpenInterfaces(HostDevice *dev)
471{
472    if (dev == nullptr) {
473        HDF_LOGE("%{public}s: %{public}d invalid param dev is nullptr", __func__, __LINE__);
474        return HDF_ERR_INVALID_PARAM;
475    }
476
477    int32_t ret =
478        memset_s(dev->devHandle, sizeof(uint8_t) * USB_MAX_INTERFACES, 0, sizeof(uint8_t) * USB_MAX_INTERFACES);
479    if (ret != EOK) {
480        HDF_LOGE("%{public}s:memset_s failed ", __func__);
481        return HDF_FAILURE;
482    }
483    dev->ctrDevHandle = UsbOpenInterface(dev->ctrIface);
484    if (dev->ctrDevHandle == nullptr) {
485        HDF_LOGE("%{public}s:ctrDevHandle UsbOpenInterface nullptr", __func__);
486        UsbdCloseInterfaces(dev);
487        return HDF_FAILURE;
488    }
489    return HDF_SUCCESS;
490}
491
492void UsbdDispatcher::RemoveDevFromService(UsbImpl *service, HostDevice *port)
493{
494    if (service == nullptr || port == nullptr) {
495        HDF_LOGE("%{public}s: service or port is nullptr", __func__);
496        return;
497    }
498
499    HdfSListIterator it;
500    HostDevice *tempPort = nullptr;
501    OsalMutexLock(&service->lock_);
502    HdfSListIteratorInit(&it, &service->devList_);
503    while (HdfSListIteratorHasNext(&it)) {
504        tempPort = reinterpret_cast<HostDevice *>(HdfSListIteratorNext(&it));
505        if (tempPort == nullptr) {
506            continue;
507        }
508        if (tempPort->busNum == port->busNum && tempPort->devAddr == port->devAddr) {
509            HdfSListIteratorRemove(&it);
510            break;
511        }
512    }
513    OsalMutexUnlock(&service->lock_);
514}
515
516int32_t UsbdDispatcher::UsbdClaimInterfaces(HostDevice *dev)
517{
518    if (dev == nullptr) {
519        HDF_LOGE("%{public}s: %{public}d invalid param dev is nullptr", __func__, __LINE__);
520        return HDF_ERR_INVALID_PARAM;
521    }
522
523    if (memset_s(dev->iface, sizeof(uint8_t) * USB_MAX_INTERFACES, 0, sizeof(uint8_t) * USB_MAX_INTERFACES) != EOK) {
524        HDF_LOGE("%{public}s:memset_s failed", __func__);
525        return HDF_FAILURE;
526    }
527
528    dev->ctrIface = GetUsbInterfaceById(const_cast<const HostDevice *>(dev), USB_CTRL_INTERFACE_ID);
529    if (dev->ctrIface == nullptr) {
530        HDF_LOGE("%{public}s:GetUsbInterfaceById nullptr", __func__);
531        UsbdReleaseInterfaces(dev);
532        return HDF_FAILURE;
533    }
534
535    return HDF_SUCCESS;
536}
537
538int32_t UsbdDispatcher::ReturnGetPipes(int32_t ret, HostDevice *dev)
539{
540    UsbdCloseInterfaces(dev);
541    UsbdReleaseInterfaces(dev);
542    dev->service->session_ = nullptr;
543    return ret;
544}
545
546int32_t UsbdDispatcher::ReturnOpenInterfaces(int32_t ret, HostDevice *dev)
547{
548    UsbdReleaseInterfaces(dev);
549    dev->service->session_ = nullptr;
550    return ret;
551}
552
553int32_t UsbdDispatcher::ReturnClainInterfaces(int32_t ret, HostDevice *dev)
554{
555    dev->service->session_ = nullptr;
556    return ret;
557}
558
559int32_t UsbdDispatcher::UsbdInit(HostDevice *dev)
560{
561    if (dev == nullptr) {
562        HDF_LOGE("%{public}s:invalid param dev", __func__);
563        return HDF_ERR_INVALID_PARAM;
564    }
565
566    if (dev->initFlag) {
567        HDF_LOGE("%{public}s:initFlag is true", __func__);
568        return HDF_SUCCESS;
569    }
570
571    int32_t ret = UsbInitHostSdk(nullptr);
572    if (ret != HDF_SUCCESS) {
573        HDF_LOGE("%{public}s:UsbInitHostSdk failed", __func__);
574        return HDF_FAILURE;
575    }
576
577    if (dev->service == nullptr) {
578        HDF_LOGE("%{public}s:dev->service is nullptr", __func__);
579        return HDF_FAILURE;
580    }
581
582    dev->service->session_ = nullptr;
583
584    ret = UsbdClaimInterfaces(dev);
585    if (ret != HDF_SUCCESS) {
586        HDF_LOGE("%{public}s:UsbdClaimInterfaces failed ret:%{public}d", __func__, ret);
587        return ReturnClainInterfaces(ret, dev);
588    }
589
590    ret = UsbdOpenInterfaces(dev);
591    if (ret != HDF_SUCCESS) {
592        HDF_LOGE("%{public}s:UsbdOpenInterfaces failed ret:%{public}d", __func__, ret);
593        return ReturnOpenInterfaces(ret, dev);
594    }
595
596    ret = UsbdGetCtrlPipe(dev);
597    if (ret != HDF_SUCCESS) {
598        HDF_LOGE("%{public}s:UsbdGetPipes failed ret:%{public}d", __func__, ret);
599        return ReturnGetPipes(ret, dev);
600    }
601    return HDF_SUCCESS;
602}
603
604int32_t UsbdDispatcher::UsbdRequestASyncRelease(UsbdRequestASync *request)
605{
606    if (request == nullptr) {
607        HDF_LOGE("%{public}s:request is nullptr.", __func__);
608        return HDF_ERR_INVALID_PARAM;
609    }
610
611    int32_t ret = HDF_SUCCESS;
612    OsalMutexLock(&request->lock);
613    UsbImpl::UsbdRequestASyncReleaseData(request);
614    if (request->reqMsg.request != nullptr) {
615        ret = UsbFreeRequest(request->reqMsg.request);
616        request->reqMsg.request = nullptr;
617        if (ret != HDF_SUCCESS) {
618            HDF_LOGE("%{public}s:UsbFreeRequest failed", __func__);
619        }
620    }
621    OsalMutexUnlock(&request->lock);
622    OsalMemFree(request);
623    return ret;
624}
625
626int32_t UsbdDispatcher::UsbdBulkASyncReqRelease(UsbdBulkASyncReqList *list)
627{
628    for (int32_t i = 0; i < USBD_BULKASYNCREQ_NUM_MAX; ++i) {
629        UsbFreeRequest(list->node[i].request);
630        list->node[i].request = nullptr;
631    }
632    DListHeadInit(&list->eList);
633    DListHeadInit(&list->uList);
634    OsalMutexDestroy(&list->elock);
635    OsalMutexDestroy(&list->ulock);
636    return HDF_SUCCESS;
637}
638
639int32_t UsbdDispatcher::UsbdBulkASyncListRelease(UsbdBulkASyncList *list)
640{
641    UsbdBulkASyncReqRelease(&list->rList);
642    OsalMutexDestroy(&list->asmHandle.lock);
643    OsalMemFree(list);
644    return HDF_SUCCESS;
645}
646
647void UsbdDispatcher::UsbdRelease(HostDevice *dev)
648{
649    if (dev == nullptr) {
650        HDF_LOGE("%{public}s: %{public}d invalid param dev is nullptr", __func__, __LINE__);
651        return;
652    }
653
654    UsbdCloseInterfaces(dev);
655    UsbdReleaseInterfaces(dev);
656    UsbdFreeCtrlPipe(dev);
657    UsbImpl::UsbdRequestSyncReleaseList(dev);
658    UsbImpl::UsbdRequestASyncReleaseList(dev);
659    UsbImpl::UsbdBulkASyncListReleasePort(dev);
660
661    if (dev->ctrlReq != nullptr) {
662        UsbFreeRequest(dev->ctrlReq);
663        dev->ctrlReq = nullptr;
664    }
665    UsbExitHostSdk(dev->service->session_);
666    dev->service->session_ = nullptr;
667    OsalMutexDestroy(&dev->writeLock);
668    OsalMutexDestroy(&dev->readLock);
669    OsalMutexDestroy(&dev->lock);
670    OsalMutexDestroy(&dev->requestLock);
671    OsalMutexDestroy(&dev->reqSyncLock);
672    OsalMutexDestroy(&dev->reqASyncLock);
673    dev->busNum = 0;
674    dev->devAddr = 0;
675    dev->initFlag = false;
676}
677
678int32_t UsbdDispatcher::UsbdMallocAndFill(uint8_t *&dataAddr, const std::vector<uint8_t> &data)
679{
680    uint32_t length = sizeof(uint8_t) * data.size();
681    if (length == 0) {
682        HDF_LOGI("%{public}s: data is empty", __func__);
683        return HDF_SUCCESS;
684    }
685
686    dataAddr = static_cast<uint8_t *>(OsalMemCalloc(length));
687    if (dataAddr == nullptr) {
688        HDF_LOGE("%{public}s: OsalMemAlloc failed", __func__);
689        return HDF_FAILURE;
690    }
691
692    void *dataAddrCovert = static_cast<void *>(dataAddr);
693    int32_t err = memcpy_s(dataAddrCovert, length, data.data(), length);
694    if (err != EOK) {
695        HDF_LOGE("%{public}s: memcpy_s failed", __func__);
696        OsalMemFree(dataAddr);
697        dataAddr = nullptr;
698        return HDF_FAILURE;
699    }
700    return HDF_SUCCESS;
701}
702
703int32_t UsbdDispatcher::FillReqAyncParams(
704    UsbdRequestASync *userData, UsbPipeInfo *pipe, UsbRequestParams *params, const uint8_t *buffer, uint32_t length)
705{
706    if (userData == nullptr || pipe == nullptr || params == nullptr) {
707        HDF_LOGE("%{public}s:invalid param", __func__);
708        return HDF_ERR_INVALID_PARAM;
709    }
710
711    bool bWrite = (pipe->pipeDirection == USB_PIPE_DIRECTION_OUT);
712    params->interfaceId = pipe->interfaceId;
713    params->pipeAddress = pipe->pipeDirection | pipe->pipeAddress;
714    params->pipeId = pipe->pipeId;
715    params->requestType = USB_REQUEST_PARAMS_DATA_TYPE;
716    params->timeout = USB_CTRL_SET_TIMEOUT;
717    params->dataReq.numIsoPackets = 0;
718    params->userData = static_cast<void *>(userData);
719    params->dataReq.length = length;
720    params->dataReq.directon = static_cast<UsbRequestDirection>((pipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & 0x1);
721    if (bWrite) {
722        params->callback = UsbdWriteCallback;
723        params->dataReq.buffer = const_cast<uint8_t *>(buffer);
724    } else {
725        params->callback = UsbdReadCallback;
726        params->dataReq.length = length;
727    }
728    return HDF_SUCCESS;
729}
730
731UsbdRequestASync *UsbdDispatcher::UsbdRequestASyncAlloc(void)
732{
733    UsbdRequestASync *req = static_cast<UsbdRequestASync *>(OsalMemCalloc(sizeof(UsbdRequestASync)));
734    if (req == nullptr) {
735        HDF_LOGE("%{public}s: OsalMemCalloc failed", __func__);
736        return req;
737    }
738
739    req->reqMsg.request = nullptr;
740    req->endPointAddr = 0;
741    req->ifHandle = nullptr;
742    req->status = 0;
743    OsalMutexInit(&req->lock);
744    return req;
745}
746
747int32_t UsbdDispatcher::UsbdRequestASyncInit(
748    HostDevice *port, UsbInterfaceHandle *ifHandle, UsbPipeInfo *pipe, UsbdRequestASync *request)
749{
750    if (port == nullptr || request == nullptr || ifHandle == nullptr || pipe == nullptr) {
751        HDF_LOGE("%{public}s:invalid param", __func__);
752        return HDF_ERR_INVALID_PARAM;
753    }
754
755    int32_t ret = memcpy_s(&request->pipe, sizeof(UsbPipeInfo), pipe, sizeof(UsbPipeInfo));
756    if (ret != EOK) {
757        HDF_LOGE("%{public}s:%{public}d memcpy_s failed", __func__, ret);
758        return ret;
759    }
760
761    request->ifHandle = ifHandle;
762    request->reqMsg.request = UsbAllocRequest(request->ifHandle, 0, request->pipe.maxPacketSize);
763    if (request->reqMsg.request == nullptr) {
764        HDF_LOGE("%{public}s:alloc request failed", __func__);
765        return HDF_ERR_MALLOC_FAIL;
766    }
767    FillReqAyncParams(request, &request->pipe, &request->params, nullptr, 0);
768    OsalMutexLock(&port->reqASyncLock);
769    HdfSListAddTail(&port->reqASyncList, &request->node);
770    OsalMutexUnlock(&port->reqASyncLock);
771    return HDF_SUCCESS;
772}
773
774UsbdRequestASync *UsbdDispatcher::UsbdRequestASyncCreatAndInsert(
775    HostDevice *port, uint8_t interfaceId, uint8_t pipeAddr)
776{
777    UsbPipeInfo pipe;
778    if (memset_s(&pipe, sizeof(UsbPipeInfo), 0, sizeof(UsbPipeInfo)) != EOK) {
779        HDF_LOGE("%{public}s:memset_s failed", __func__);
780        return nullptr;
781    }
782
783    int32_t ret = GetPipe(port, interfaceId, pipeAddr, &pipe);
784    if (ret != HDF_SUCCESS) {
785        HDF_LOGE("%{public}s: get pipe info failed interfaceId=%{public}d, pipeAddr=%{public}d", __func__, interfaceId,
786            pipeAddr);
787        return nullptr;
788    }
789
790    UsbInterfaceHandle *ifHandle = UsbImpl::InterfaceIdToHandle(port, interfaceId);
791    if (ifHandle == nullptr) {
792        HDF_LOGE("%{public}s:get interface handle failed", __func__);
793        return nullptr;
794    }
795
796    UsbdRequestASync *req = UsbdRequestASyncAlloc();
797    if (req == nullptr) {
798        HDF_LOGE("%{public}s: UsbdRequestASyncAlloc failed", __func__);
799        return req;
800    }
801    ret = UsbdRequestASyncInit(port, ifHandle, &pipe, req);
802    if (ret != HDF_SUCCESS) {
803        HDF_LOGE("%{public}s:UsbdRequestASyncInit failed:%{public}d", __func__, ret);
804        UsbdRequestASyncRelease(req);
805        req = nullptr;
806        return req;
807    }
808    return req;
809}
810
811int32_t UsbdDispatcher::HostDeviceInit(HostDevice *port)
812{
813    if (port == nullptr) {
814        HDF_LOGE("%{public}s:port is nullptr", __func__);
815        return HDF_ERR_INVALID_OBJECT;
816    }
817
818    port->busNum = 0;
819    port->devAddr = 0;
820    port->initFlag = false;
821    port->interfaceCnt = 0;
822    if (OsalMutexInit(&port->lock) != HDF_SUCCESS) {
823        HDF_LOGE("%{public}s:init lock failed!", __func__);
824        return HDF_FAILURE;
825    }
826
827    if (OsalMutexInit(&port->requestLock) != HDF_SUCCESS) {
828        HDF_LOGE("%{public}s:init requestLock failed!", __func__);
829        return HDF_FAILURE;
830    }
831
832    if (OsalMutexInit(&port->writeLock) != HDF_SUCCESS) {
833        HDF_LOGE("%{public}s:init writeLock failed!", __func__);
834        return HDF_FAILURE;
835    }
836
837    if (OsalMutexInit(&port->readLock) != HDF_SUCCESS) {
838        HDF_LOGE("%{public}s:init readLock failed!", __func__);
839        return HDF_FAILURE;
840    }
841
842    if (OsalMutexInit(&port->reqSyncLock) != HDF_SUCCESS) {
843        HDF_LOGE("%{public}s:init reqSyncLock failed!", __func__);
844        return HDF_FAILURE;
845    }
846
847    if (OsalMutexInit(&port->reqASyncLock) != HDF_SUCCESS) {
848        HDF_LOGE("%{public}s:init reqASyncLock failed!", __func__);
849        return HDF_FAILURE;
850    }
851
852    HdfSListInit(&port->requestQueue);
853    HdfSListInit(&port->reqSyncList);
854    HdfSListInit(&port->reqASyncList);
855    return HDF_SUCCESS;
856}
857
858int32_t UsbdDispatcher::HostDeviceCreate(HostDevice **port)
859{
860    if (port == nullptr) {
861        HDF_LOGE("%{public}s:invalid param port is nullptr", __func__);
862        return HDF_ERR_INVALID_OBJECT;
863    }
864
865    HostDevice *tmp = static_cast<HostDevice *>(OsalMemCalloc(sizeof(HostDevice)));
866    if (tmp == nullptr) {
867        HDF_LOGE("%{public}s:OsalMemCalloc failed", __func__);
868        return HDF_ERR_MALLOC_FAIL;
869    }
870
871    int32_t ret = HostDeviceInit(tmp);
872    if (ret != HDF_SUCCESS) {
873        HDF_LOGE("%{public}s:HostDeviceInit failed!", __func__);
874        OsalMemFree(tmp);
875        tmp = nullptr;
876        return ret;
877    }
878
879    tmp->initFlag = false;
880    *port = tmp;
881    return HDF_SUCCESS;
882}
883
884int32_t UsbdDispatcher::FunAttachDevice(HostDevice *port, HdfSBuf *data, HdfSBuf *reply)
885{
886    if (port == nullptr) {
887        HDF_LOGE("%{public}s:mangf invalid param", __func__);
888        return HDF_ERR_INVALID_PARAM;
889    }
890    if (port->initFlag) {
891        HDF_LOGD("%{public}s:device is already on flag:%{public}d bus:%{public}d dev:%{public}d", __func__,
892            port->initFlag, port->busNum, port->devAddr);
893        return HDF_SUCCESS;
894    }
895
896    int32_t ret = HDF_SUCCESS;
897    do {
898        ret = UsbdInit(port);
899        if (ret != HDF_SUCCESS) {
900            HDF_LOGE("%{public}s:UsbInit failed ret:%{public}d", __func__, ret);
901            RemoveDevFromService(port->service, port);
902            UsbdRelease(port);
903            OsalMemFree(port);
904            return ret;
905        }
906        ret = UsbdAllocFifo(&port->readFifo, READ_BUF_SIZE);
907        if (ret != HDF_SUCCESS) {
908            HDF_LOGE("%{public}s:UsbAllocFifo failed ret:%{public}d", __func__, ret);
909            ret = HDF_ERR_INVALID_PARAM;
910            break;
911        }
912        if (ret == HDF_SUCCESS) {
913            port->initFlag = true;
914            HDF_LOGI("%{public}s:UsbOpen success", __func__);
915        } else {
916            HDF_LOGE("%{public}s:UsbOpen fail:%{public}d", __func__, ret);
917        }
918        return ret;
919    } while (0);
920
921    UsbdFreeFifo(&port->readFifo);
922    UsbdRelease(port);
923    RemoveDevFromService(port->service, port);
924    OsalMemFree(port);
925    return ret;
926}
927
928int32_t UsbdDispatcher::UsbdDeviceCreateAndAttach(const sptr<UsbImpl> &service, uint8_t busNum, uint8_t devAddr)
929{
930    HostDevice *port = service->FindDevFromService(busNum, devAddr);
931    if (port != nullptr) {
932        HDF_LOGI("%{public}s:device already add", __func__);
933        return HDF_ERR_DEVICE_BUSY;
934    }
935    int32_t ret = HostDeviceCreate(&port);
936    if (ret == HDF_SUCCESS) {
937        port->busNum = busNum;
938        port->devAddr = devAddr;
939        port->service = service;
940        OsalMutexLock(&service->lock_);
941        HdfSListAdd(&service->devList_, &port->node);
942        OsalMutexUnlock(&service->lock_);
943        ret = FunAttachDevice(port, nullptr, nullptr);
944        if (ret != HDF_SUCCESS) {
945            HDF_LOGW("%{public}s:FunAttachDevice error ret:%{public}d", __func__, ret);
946        }
947        port = nullptr;
948    } else {
949        HDF_LOGE("%{public}s:createdevice error ret:%{public}d", __func__, ret);
950    }
951    return ret;
952}
953
954int32_t UsbdDispatcher::FunDetachDevice(HostDevice *port, HdfSBuf *data)
955{
956    if (port == nullptr) {
957        HDF_LOGE("%{public}s:invalid param port", __func__);
958        return HDF_ERR_INVALID_PARAM;
959    }
960
961    RemoveDevFromService(port->service, port);
962    UsbdRelease(port);
963    UsbdFreeFifo(&port->readFifo);
964    OsalMemFree(port);
965    return HDF_SUCCESS;
966}
967
968int32_t UsbdDispatcher::UsbdDeviceDettach(UsbImpl *service, uint8_t busNum, uint8_t devAddr)
969{
970    if (service == nullptr) {
971        HDF_LOGE("%{public}s:invalid param service!", __func__);
972        return HDF_ERR_INVALID_PARAM;
973    }
974
975    HostDevice *port = service->FindDevFromService(busNum, devAddr);
976    if (port == nullptr) {
977        HDF_LOGE("%{public}s:FindDevFromService failed", __func__);
978        return HDF_DEV_ERR_NO_DEVICE;
979    }
980
981    int32_t ret = FunDetachDevice(port, nullptr);
982    if (ret != HDF_SUCCESS) {
983        HDF_LOGE("%{public}s: %{public}d FunDetachDevice failed", __func__, ret);
984        return HDF_FAILURE;
985    }
986
987    return HDF_SUCCESS;
988}
989
990HostDevice *UsbdDispatcher::UsbdFindDevForBusNum(UsbImpl *service, uint8_t busNum)
991{
992    if (service == nullptr) {
993        HDF_LOGE("%{public}s: service is nullptr", __func__);
994        return nullptr;
995    }
996
997    uint8_t flag = false;
998    HdfSListIterator it;
999    HostDevice *tempPort = nullptr;
1000    OsalMutexLock(&service->lock_);
1001    HdfSListIteratorInit(&it, &service->devList_);
1002    while (HdfSListIteratorHasNext(&it)) {
1003        tempPort = reinterpret_cast<HostDevice *>(HdfSListIteratorNext(&it));
1004        if (!tempPort) {
1005            continue;
1006        }
1007        if (tempPort->busNum == busNum) {
1008            HdfSListIteratorRemove(&it);
1009            flag = true;
1010            break;
1011        }
1012    }
1013    OsalMutexUnlock(&service->lock_);
1014    if (flag) {
1015        return tempPort;
1016    }
1017    return nullptr;
1018}
1019
1020int32_t UsbdDispatcher::UsbdRemoveBusDev(UsbImpl *service, uint8_t busNum, const sptr<IUsbdSubscriber> &subscriber)
1021{
1022    HostDevice *tempPort = nullptr;
1023    USBDeviceInfo info;
1024    int32_t ret = HDF_FAILURE;
1025
1026    while (1) {
1027        tempPort = UsbdDispatcher::UsbdFindDevForBusNum(service, busNum);
1028        if (!tempPort) {
1029            break;
1030        }
1031        info = {ACT_DEVDOWN, tempPort->busNum, tempPort->devAddr};
1032        ret = subscriber->DeviceEvent(info);
1033        if (ret != HDF_SUCCESS) {
1034            HDF_LOGE("%{public}s failed to notify subscriber, ret: %{public}d", __func__, ret);
1035            return ret;
1036        }
1037        UsbdRelease(tempPort);
1038        UsbdFreeFifo(&tempPort->readFifo);
1039        OsalMemFree(tempPort);
1040    }
1041    return ret;
1042}
1043
1044int32_t UsbdDispatcher::UsbdBulkASyncReqInit(UsbdBulkASyncReqList *list, UsbdBulkASyncList *pList)
1045{
1046    int32_t ret = HDF_SUCCESS;
1047    int32_t i = 0;
1048    DListHeadInit(&list->eList);
1049    DListHeadInit(&list->uList);
1050    OsalMutexInit(&list->elock);
1051    OsalMutexInit(&list->ulock);
1052    for (i = 0; i < USBD_BULKASYNCREQ_NUM_MAX; ++i) {
1053        list->node[i].request = UsbAllocRequest(pList->ifHandle, 0, pList->pipe.maxPacketSize);
1054        if (!list->node[i].request) {
1055            HDF_LOGE("%{public}s:alloc request failed i:%{public}d", __func__, i);
1056            ret = HDF_ERR_MALLOC_FAIL;
1057            break;
1058        }
1059        list->node[i].list = list;
1060        list->node[i].id = i;
1061        DListInsertTail(&list->node[i].node, &list->eList);
1062        pList->params.userData = static_cast<void *>(&list->node[i]);
1063    }
1064
1065    if (i != USBD_BULKASYNCREQ_NUM_MAX) {
1066        for (; i >= 0; --i) {
1067            UsbFreeRequest(list->node[i].request);
1068            list->node[i].request = nullptr;
1069        }
1070        DListHeadInit(&list->eList);
1071        DListHeadInit(&list->uList);
1072        OsalMutexDestroy(&list->elock);
1073        OsalMutexDestroy(&list->ulock);
1074    }
1075    list->pList = pList;
1076    return ret;
1077}
1078
1079UsbdBulkASyncList *UsbdDispatcher::UsbdBulkASyncListAlloc(HostDevice *port, uint8_t ifId, uint8_t epId)
1080{
1081    UsbPipeInfo pipe;
1082    if (memset_s(&pipe, sizeof(UsbPipeInfo), 0, sizeof(UsbPipeInfo)) != EOK) {
1083        HDF_LOGE("%{public}s:memset_s failed", __func__);
1084        return nullptr;
1085    }
1086
1087    int32_t ret = GetPipe(port, ifId, epId, &pipe);
1088    if (ret != HDF_SUCCESS) {
1089        HDF_LOGE("%{public}s:GetPipe failed, ret:%{public}d", __func__, ret);
1090        return nullptr;
1091    }
1092
1093    UsbInterfaceHandle *ifHandle = UsbImpl::InterfaceIdToHandle(port, ifId);
1094    if (ifHandle == nullptr) {
1095        HDF_LOGE("%{public}s:get interface handle failed", __func__);
1096        return nullptr;
1097    }
1098
1099    UsbdBulkASyncList *bulkAsyncList = reinterpret_cast<UsbdBulkASyncList *>(OsalMemCalloc(sizeof(UsbdBulkASyncList)));
1100    if (bulkAsyncList == nullptr) {
1101        HDF_LOGE("%{public}s:malloc failed!", __func__);
1102        return nullptr;
1103    }
1104    bulkAsyncList->ifId = ifId;
1105    bulkAsyncList->epId = epId;
1106    bulkAsyncList->instance = port;
1107    OsalMutexInit(&bulkAsyncList->asmHandle.lock);
1108    bulkAsyncList->pipe = pipe;
1109    bulkAsyncList->ifHandle = ifHandle;
1110    UsbdBulkASyncReqFillParams(&bulkAsyncList->pipe, &bulkAsyncList->params, nullptr);
1111    ret = UsbdBulkASyncReqInit(&bulkAsyncList->rList, bulkAsyncList);
1112    if (ret != HDF_SUCCESS) {
1113        HDF_LOGE("%{public}s: UsbdBulkASyncReqInit failed ret:%{public}d", __func__, ret);
1114        UsbdBulkASyncListRelease(bulkAsyncList);
1115        bulkAsyncList = nullptr;
1116        return bulkAsyncList;
1117    }
1118
1119    return bulkAsyncList;
1120}
1121
1122int32_t UsbdDispatcher::UsbdBulkASyncReqNodeSetNoUse(UsbdBulkASyncReqNode *db)
1123{
1124    OsalMutexLock(&db->list->elock);
1125    db->use = USBD_REQNODE_NOUSE;
1126    DListInsertTail(&db->node, &db->list->eList);
1127    OsalMutexUnlock(&db->list->elock);
1128    return HDF_SUCCESS;
1129}
1130
1131UsbdBulkASyncReqNode *UsbdDispatcher::UsbdBulkASyncReqGetENode(UsbdBulkASyncReqList *list)
1132{
1133    OsalMutexLock(&list->elock);
1134    if (DListIsEmpty(&list->eList)) {
1135        OsalMutexUnlock(&list->elock);
1136        HDF_LOGE("%{public}s:invalid param", __func__);
1137        return nullptr;
1138    }
1139    UsbdBulkASyncReqNode *ptr = DLIST_FIRST_ENTRY(&list->eList, UsbdBulkASyncReqNode, node);
1140    if (ptr != nullptr) {
1141        ptr->use = USBD_REQNODE_OTHER;
1142        DListRemove(&ptr->node);
1143    }
1144    OsalMutexUnlock(&list->elock);
1145    return ptr;
1146}
1147
1148int32_t UsbdDispatcher::UsbdBulkReadRemoteCallback(
1149    const sptr<IUsbdBulkCallback> &service, int32_t status, UsbdBufferHandle *handle)
1150{
1151    if (service == nullptr || handle == nullptr) {
1152        HDF_LOGE("%{public}s:invalid param", __func__);
1153        return HDF_ERR_INVALID_PARAM;
1154    }
1155
1156    OsalMutexLock(&handle->lock);
1157    uint8_t flag = handle->cbflg;
1158    handle->cbflg = 1;
1159    int32_t actLength = static_cast<int32_t>(handle->rcur);
1160    OsalMutexUnlock(&handle->lock);
1161    if (flag) {
1162        return HDF_SUCCESS;
1163    }
1164    int32_t ret = service->OnBulkReadCallback(status, actLength);
1165    if (ret != HDF_SUCCESS) {
1166        HDF_LOGE("%{public}s:OnBulkReadCallback failed, ret=%{public}d", __func__, ret);
1167    }
1168    return ret;
1169}
1170
1171int32_t UsbdDispatcher::UsbdBulkWriteRemoteCallback(
1172    const sptr<IUsbdBulkCallback> &service, int32_t status, UsbdBufferHandle *handle)
1173{
1174    if (service == nullptr || handle == nullptr) {
1175        HDF_LOGE("%{public}s:invalid param", __func__);
1176        return HDF_ERR_INVALID_PARAM;
1177    }
1178
1179    OsalMutexLock(&handle->lock);
1180    uint8_t flag = handle->cbflg;
1181    handle->cbflg = 1;
1182    int32_t actLength = static_cast<int32_t>(handle->cur);
1183    OsalMutexUnlock(&handle->lock);
1184    if (flag) {
1185        return HDF_SUCCESS;
1186    }
1187
1188    int32_t ret = service->OnBulkWriteCallback(status, actLength);
1189    if (ret != HDF_SUCCESS) {
1190        HDF_LOGE("%{public}s:OnBulkWriteCallback failed, ret=%{public}d", __func__, ret);
1191    }
1192    return ret;
1193}
1194
1195int32_t UsbdDispatcher::UsbdBulkASyncPutAsmData(UsbdBufferHandle *handle, uint8_t *buffer, uint32_t len)
1196{
1197    if (handle == nullptr || buffer == nullptr || len < 1) {
1198        HDF_LOGE("%{public}s:invalid param len:%{public}d", __func__, len);
1199        return HDF_ERR_INVALID_PARAM;
1200    }
1201
1202    int32_t ret = HDF_SUCCESS;
1203    OsalMutexLock(&handle->lock);
1204    do {
1205        if (handle->fd < 1) {
1206            HDF_LOGE("%{public}s:fd error, handle->fd:%{public}d", __func__, handle->fd);
1207            ret = HDF_ERR_BAD_FD;
1208            break;
1209        }
1210        uint32_t tlen = (handle->size > handle->rcur) ? (handle->size - handle->rcur) : 0;
1211        tlen = tlen < len ? tlen : len;
1212        if (tlen > 0) {
1213            ret = memcpy_s(handle->starAddr + handle->rcur, tlen, buffer, len);
1214            if (ret != EOK) {
1215                HDF_LOGE("%{public}s:%{public}d memcpy_s failed", __func__, ret);
1216                OsalMutexUnlock(&handle->lock);
1217                return ret;
1218            }
1219
1220            handle->rcur += tlen;
1221        }
1222    } while (0);
1223    OsalMutexUnlock(&handle->lock);
1224    return ret;
1225}
1226
1227int32_t UsbdDispatcher::UsbdBulkAsyncGetAsmData(
1228    UsbdBufferHandle *handle, UsbRequestParams *params, uint16_t maxPacketSize)
1229{
1230    if (handle == nullptr || params == nullptr || handle->size < 1 || maxPacketSize < 1) {
1231        HDF_LOGE("%{public}s:invalid param", __func__);
1232        return HDF_ERR_INVALID_PARAM;
1233    }
1234
1235    int32_t ret = HDF_ERR_INVALID_PARAM;
1236    OsalMutexLock(&handle->lock);
1237    if (handle->cur < handle->size) {
1238        params->dataReq.length =
1239            (handle->size - handle->cur) < maxPacketSize ? (handle->size - handle->cur) : maxPacketSize;
1240        params->dataReq.buffer = handle->starAddr + handle->cur;
1241        handle->cur += params->dataReq.length;
1242        ret = HDF_SUCCESS;
1243    } else {
1244        params->dataReq.length = 0;
1245        params->dataReq.buffer = nullptr;
1246        HDF_LOGE("%{public}s:invalid param", __func__);
1247        ret = HDF_DEV_ERR_NODATA;
1248    }
1249    OsalMutexUnlock(&handle->lock);
1250    return ret;
1251}
1252
1253int32_t UsbdDispatcher::UsbdBulkAsyncGetAsmReqLen(UsbdBufferHandle *handle, uint32_t *reqLen, uint16_t maxPacketSize)
1254{
1255    if (handle == nullptr || reqLen == nullptr || handle->size < 1 || maxPacketSize < 1) {
1256        HDF_LOGE("%{public}s:%{public}d invalid param", __func__, __LINE__);
1257        return HDF_ERR_INVALID_PARAM;
1258    }
1259
1260    uint32_t tlen = 0;
1261    OsalMutexLock(&handle->lock);
1262    if (handle->cur < handle->size) {
1263        tlen = handle->size - handle->cur;
1264        tlen = tlen < maxPacketSize ? tlen : maxPacketSize;
1265        handle->cur += tlen;
1266    }
1267    OsalMutexUnlock(&handle->lock);
1268    *reqLen = tlen;
1269    return HDF_SUCCESS;
1270}
1271
1272int32_t UsbdDispatcher::UsbdBulkASyncReqWriteAutoSubmit(UsbRequest *request)
1273{
1274    UsbRequestParams params;
1275    UsbdBulkASyncReqNode *db = static_cast<UsbdBulkASyncReqNode *>(request->compInfo.userData);
1276    int32_t ret = memcpy_s(&params, sizeof(params), &db->list->pList->params, sizeof(params));
1277    if (ret != EOK) {
1278        HDF_LOGE("%{public}s:%{public}d memcpy_s failed", __func__, ret);
1279        return ret;
1280    }
1281
1282    params.userData = static_cast<void *>(db);
1283    ret = UsbdBulkAsyncGetAsmData(&db->list->pList->asmHandle, &params, db->list->pList->pipe.maxPacketSize);
1284    if (ret != HDF_SUCCESS) {
1285        UsbdBulkASyncReqNodeSetNoUse(db);
1286        return ret;
1287    }
1288    db->request->compInfo.status = USB_REQUEST_COMPLETED;
1289    ret = UsbFillRequest(request, db->list->pList->ifHandle, &params);
1290    if (ret != HDF_SUCCESS) {
1291        UsbdBulkASyncReqNodeSetNoUse(db);
1292        HDF_LOGE("%{public}s:UsbFillRequest ret:%{public}d", __func__, ret);
1293        return ret;
1294    }
1295    ret = UsbSubmitRequestAsync(request);
1296    if (ret != HDF_SUCCESS) {
1297        UsbdBulkASyncReqNodeSetNoUse(db);
1298        HDF_LOGE("%{public}s:UsbSubmitRequestAsync ret:%{public}d", __func__, ret);
1299    }
1300    return ret;
1301}
1302
1303int32_t UsbdDispatcher::UsbdBulkASyncReqReadAutoSubmit(UsbRequest *request)
1304{
1305    uint32_t readLen = 0;
1306    UsbdBulkASyncReqNode *db = static_cast<UsbdBulkASyncReqNode *>(request->compInfo.userData);
1307    int32_t ret =
1308        UsbdBulkASyncPutAsmData(&db->list->pList->asmHandle, request->compInfo.buffer, request->compInfo.actualLength);
1309    if (ret != HDF_SUCCESS) {
1310        HDF_LOGE("%{public}s:%{public}d UsbdBulkASyncPutAsmData error size:%{public}d ret:%{public}d", __func__,
1311            __LINE__, request->compInfo.actualLength, ret);
1312        UsbdBulkASyncReqNodeSetNoUse(db);
1313        return ret;
1314    }
1315
1316    ret = UsbdBulkAsyncGetAsmReqLen(&db->list->pList->asmHandle, &readLen, db->list->pList->pipe.maxPacketSize);
1317    if (ret != HDF_SUCCESS || readLen < 1) {
1318        UsbdBulkASyncReqNodeSetNoUse(db);
1319        HDF_LOGE("%{public}s:invalid param", __func__);
1320        return HDF_DEV_ERR_NODATA;
1321    }
1322    db->request->compInfo.status = USB_REQUEST_COMPLETED;
1323    UsbHostRequest *hostRequest = reinterpret_cast<UsbIfRequest *>(request)->hostRequest;
1324    if (readLen != static_cast<uint32_t>(hostRequest->length)) {
1325        UsbRequestParams params;
1326        ret = memcpy_s(&params, sizeof(params), &db->list->pList->params, sizeof(params));
1327        if (ret != EOK) {
1328            HDF_LOGE("%{public}s: %{public}d memcpy_s failed", __func__, ret);
1329            return ret;
1330        }
1331
1332        params.dataReq.length = readLen;
1333        params.userData = static_cast<void *>(db);
1334        ret = UsbFillRequest(request, db->list->pList->ifHandle, &params);
1335        if (ret != HDF_SUCCESS) {
1336            UsbdBulkASyncReqNodeSetNoUse(db);
1337            HDF_LOGE("%{public}s:UsbFillRequest ret:%{public}d ", __func__, ret);
1338            return ret;
1339        }
1340    }
1341    ret = UsbSubmitRequestAsync(request);
1342    if (ret != HDF_SUCCESS) {
1343        UsbdBulkASyncReqNodeSetNoUse(db);
1344        HDF_LOGE("%{public}s:UsbSubmitRequestAsync ret:%{public}d ", __func__, ret);
1345    }
1346    return ret;
1347}
1348
1349void UsbdDispatcher::UsbdBulkASyncWriteCallbackAutoSubmit(UsbRequest *request)
1350{
1351    if (request == nullptr) {
1352        HDF_LOGE("%{public}s: %{public}d request is nullptr", __func__, __LINE__);
1353        return;
1354    }
1355
1356    int32_t ret = HDF_SUCCESS;
1357    UsbdBulkASyncReqNode *node = static_cast<UsbdBulkASyncReqNode *>(request->compInfo.userData);
1358    int32_t status = request->compInfo.status;
1359    if (status != 0) {
1360        UsbdBulkASyncReqNodeSetNoUse(node);
1361        ret = UsbdBulkWriteRemoteCallback(node->list->pList->cb, status, &node->list->pList->asmHandle);
1362        if (ret != HDF_SUCCESS) {
1363            HDF_LOGE("%{public}s:%{public}d UsbdBulkWriteRemoteCallback failed, ret:%{public}d"
1364                "id:%{public}d status:%{public}d", __func__, __LINE__, ret, node->id, status);
1365        }
1366        return;
1367    }
1368
1369    ret = UsbdBulkASyncReqWriteAutoSubmit(request);
1370    if (ret == HDF_DEV_ERR_NODATA) {
1371        int32_t count = DListGetCount(&node->list->eList);
1372        if (count >= USBD_BULKASYNCREQ_NUM_MAX) {
1373            ret = UsbdBulkWriteRemoteCallback(node->list->pList->cb, HDF_SUCCESS, &node->list->pList->asmHandle);
1374            if (ret != HDF_SUCCESS) {
1375                HDF_LOGE("%{public}s: %{public}d UsbdBulkWriteRemoteCallback failed", __func__, __LINE__);
1376            }
1377            return;
1378        }
1379    } else if (ret != HDF_SUCCESS) {
1380        ret = UsbdBulkWriteRemoteCallback(node->list->pList->cb, ret, &node->list->pList->asmHandle);
1381        if (ret != HDF_SUCCESS) {
1382            HDF_LOGE(
1383                "%{public}s:%{public}d UsbdBulkWriteRemoteCallback failed ret:%{public}d id:%{public}d",
1384                __func__, __LINE__, ret, node->id);
1385        }
1386        return;
1387    }
1388}
1389
1390void UsbdDispatcher::UsbdBulkASyncReadCallbackAutoSubmit(UsbRequest *request)
1391{
1392    if (request == nullptr) {
1393        HDF_LOGE("%{public}s: %{public}d request is nullptr", __func__, __LINE__);
1394        return;
1395    }
1396
1397    int32_t ret = HDF_SUCCESS;
1398    UsbdBulkASyncReqNode *node = static_cast<UsbdBulkASyncReqNode *>(request->compInfo.userData);
1399    int32_t status = request->compInfo.status;
1400    if (status != 0) {
1401        UsbdBulkASyncReqNodeSetNoUse(node);
1402        ret = UsbdBulkReadRemoteCallback(node->list->pList->cb, status, &node->list->pList->asmHandle);
1403        if (ret != HDF_SUCCESS) {
1404            HDF_LOGE("%{public}s:%{public}d UsbdBulkReadRemoteCallback failed, ret:%{public}d"
1405                "id:%{public}d status:%{public}d", __func__, __LINE__, ret, node->id, status);
1406        }
1407        return;
1408    }
1409
1410    ret = UsbdBulkASyncReqReadAutoSubmit(request);
1411    if (ret == HDF_DEV_ERR_NODATA) {
1412        int32_t count = DListGetCount(&node->list->eList);
1413        if (count >= USBD_BULKASYNCREQ_NUM_MAX) {
1414            ret = UsbdBulkReadRemoteCallback(node->list->pList->cb, HDF_SUCCESS, &node->list->pList->asmHandle);
1415            if (ret != HDF_SUCCESS) {
1416                HDF_LOGE("%{public}s: %{public}d UsbdBulkReadRemoteCallback failed", __func__, __LINE__);
1417            }
1418            return;
1419        }
1420    } else if (ret != HDF_SUCCESS) {
1421        ret = UsbdBulkReadRemoteCallback(node->list->pList->cb, ret, &node->list->pList->asmHandle);
1422        if (ret != HDF_SUCCESS) {
1423            HDF_LOGE(
1424                "%{public}s:%{public}d UsbdBulkReadRemoteCallback failed ret:%{public}d id:%{public}d",
1425                __func__, __LINE__, ret, node->id);
1426        }
1427        return;
1428    }
1429}
1430
1431int32_t UsbdDispatcher::UsbdBulkASyncReqFillParams(UsbPipeInfo *pipe, UsbRequestParams *params, uint8_t *buffer)
1432{
1433    params->interfaceId = pipe->interfaceId;
1434    params->pipeAddress = pipe->pipeDirection | pipe->pipeAddress;
1435    params->pipeId = pipe->pipeId;
1436    params->requestType = USB_REQUEST_PARAMS_DATA_TYPE;
1437    params->timeout = USB_CTRL_SET_TIMEOUT;
1438    params->dataReq.numIsoPackets = 0;
1439    params->dataReq.directon = static_cast<UsbRequestDirection>((pipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & 0x1);
1440    params->dataReq.length = pipe->maxPacketSize;
1441
1442    if (pipe->pipeDirection == USB_PIPE_DIRECTION_OUT) {
1443        params->callback = UsbdBulkASyncWriteCallbackAutoSubmit;
1444        params->dataReq.buffer = buffer;
1445    } else {
1446        params->callback = UsbdBulkASyncReadCallbackAutoSubmit;
1447    }
1448    return HDF_SUCCESS;
1449}
1450
1451int32_t UsbdDispatcher::UsbdBulkASyncReqWriteSubmit(UsbdBulkASyncReqNode *req)
1452{
1453    UsbRequestParams params;
1454    int32_t ret = memcpy_s(&params, sizeof(params), &req->list->pList->params, sizeof(params));
1455    if (ret != EOK) {
1456        HDF_LOGE("%{public}s:%{public}d memcpy_s failed", __func__, ret);
1457        return ret;
1458    }
1459
1460    params.userData = static_cast<void *>(req);
1461    ret = UsbdBulkAsyncGetAsmData(&req->list->pList->asmHandle, &params, req->list->pList->pipe.maxPacketSize);
1462    if (ret != HDF_SUCCESS) {
1463        UsbdBulkASyncReqNodeSetNoUse(req);
1464        HDF_LOGE("%{public}s:UsbdBulkAsyncGetAsmData ret:%{public}d", __func__, ret);
1465        return ret;
1466    }
1467    req->request->compInfo.status = USB_REQUEST_COMPLETED;
1468    ret = UsbFillRequest(req->request, req->list->pList->ifHandle, &params);
1469    if (ret != HDF_SUCCESS) {
1470        UsbdBulkASyncReqNodeSetNoUse(req);
1471        HDF_LOGE("%{public}s:UsbFillRequest ret:%{public}d", __func__, ret);
1472        return ret;
1473    }
1474    ret = UsbSubmitRequestAsync(req->request);
1475    if (ret != HDF_SUCCESS) {
1476        UsbdBulkASyncReqNodeSetNoUse(req);
1477        HDF_LOGE("%{public}s:UsbSubmitRequestAsync ret:%{public}d", __func__, ret);
1478    }
1479    return ret;
1480}
1481
1482int32_t UsbdDispatcher::UsbdBulkASyncReqReadSubmit(UsbdBulkASyncReqNode *db)
1483{
1484    uint32_t readLen = 0;
1485    int32_t ret = UsbdBulkAsyncGetAsmReqLen(&db->list->pList->asmHandle, &readLen, db->list->pList->pipe.maxPacketSize);
1486    if (ret != HDF_SUCCESS || readLen == 0) {
1487        UsbdBulkASyncReqNodeSetNoUse(db);
1488        HDF_LOGE("%{public}s:UsbdBulkAsyncGetAsmReqLen failed, readLen:%{public}u", __func__, readLen);
1489        return HDF_DEV_ERR_NODATA;
1490    }
1491
1492    db->request->compInfo.status = USB_REQUEST_COMPLETED;
1493    UsbRequestParams params;
1494    ret = memcpy_s(&params, sizeof(params), &db->list->pList->params, sizeof(params));
1495    if (ret != EOK) {
1496        HDF_LOGE("%{public}s:%{public}d memcpy_s failed", __func__, ret);
1497        return ret;
1498    }
1499
1500    params.dataReq.length = readLen;
1501    params.userData = static_cast<void *>(db);
1502    ret = UsbFillRequest(db->request, db->list->pList->ifHandle, &params);
1503    if (ret != HDF_SUCCESS) {
1504        HDF_LOGE("%{public}s:UsbFillRequest failed", __func__);
1505        UsbdBulkASyncReqNodeSetNoUse(db);
1506        return ret;
1507    }
1508
1509    ret = UsbSubmitRequestAsync(db->request);
1510    if (ret != HDF_SUCCESS) {
1511        HDF_LOGE("%{public}s:UsbSubmitRequestAsync failed", __func__);
1512        UsbdBulkASyncReqNodeSetNoUse(db);
1513    }
1514    return ret;
1515}
1516} // namespace V1_1
1517} // namespace Usb
1518} // namespace HDI
1519} // namespace OHOS
1520