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(¶ms, 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, ¶ms, 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, ¶ms);
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(¶ms, 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, ¶ms);
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(¶ms, 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, ¶ms, 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, ¶ms);
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(¶ms, 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, ¶ms);
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