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