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