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