1/* 2 * Copyright (c) 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 "mock_linux_adapter.h" 17 18constexpr uint32_t DESCRIPTORSLENGTH = 111; 19constexpr uint32_t SEM_WAIT_FOREVER = 0xFFFFFFFF; 20constexpr uint8_t ACTIVE_NUM = 1; 21constexpr uint32_t BULK_LEN = 256; 22constexpr uint32_t CAPS = 509; 23constexpr uint8_t BLENGTH = 18; 24constexpr uint16_t BCDUSB = 800; 25constexpr uint8_t MAX_PACKET_SIZE = 9; 26constexpr uint16_t ID_VENDOR = 8711; 27constexpr uint16_t ID_PRODUCT = 24; 28constexpr uint16_t BCD_DEVICE = 547; 29constexpr uint8_t I_PRODUCT = 2; 30constexpr uint8_t I_SERIAL_NUMBER = 3; 31constexpr uint32_t CFG_LEN = 93; 32 33static UsbDeviceHandle *g_usbHandle = nullptr; 34static UsbDevice *g_dev = nullptr; 35static UsbHostRequest *g_sprq = nullptr; 36static OsalSem g_completeSem; 37 38static std::array<uint8_t, DESCRIPTORSLENGTH> g_buf = { 39 0x12, 0x01, 0x20, 0x03, 0x00, 0x00, 0x00, 0x09, 0x07, 0x22, 0x18, 0x00, 0x23, 0x02, 0x01, 0x02, 40 0x03, 0x01, 0x09, 0x02, 0x5D, 0x00, 0x02, 0x01, 0x04, 0xC0, 0x3E, 0x08, 0x0B, 0x00, 0x02, 0x02, 41 0x02, 0x01, 0x07, 0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x05, 0x05, 0x24, 0x00, 0x10, 42 0x01, 0x05, 0x24, 0x01, 0x00, 0x01, 0x04, 0x24, 0x02, 0x02, 0x05, 0x24, 0x06, 0x00, 0x01, 0x07, 43 0x05, 0x81, 0x03, 0x0A, 0x00, 0x09, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x01, 0x00, 44 0x02, 0x0A, 0x00, 0x02, 0x06, 0x07, 0x05, 0x82, 0x02, 0x00, 0x04, 0x00, 0x06, 0x30, 0x00, 0x00, 45 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x00, 0x04, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00 46}; 47 48static int32_t FillUsbDeviceHandle(UsbDeviceHandle *handle) 49{ 50 UsbDeviceDescriptor dec = {BLENGTH, 1, BCDUSB, 0, 0, 0, MAX_PACKET_SIZE, ID_VENDOR, 51 ID_PRODUCT, BCD_DEVICE, 1, I_PRODUCT, I_SERIAL_NUMBER, 1}; 52 53 handle->claimedInterfaces = 0; 54 handle->caps = CAPS; 55 handle->dev->portNum = 0; 56 handle->dev->speed = USB_DDK_SPEED_UNKNOWN; 57 handle->dev->activeConfig = 0; 58 handle->dev->deviceDescriptor = dec; 59 handle->dev->configDescriptors->actualLen = CFG_LEN; 60 return HDF_SUCCESS; 61} 62 63int32_t FuncAdapterInit(const UsbSession *session) 64{ 65 (void)session; 66 OsalSemInit(&g_completeSem, 0); 67 return HDF_SUCCESS; 68} 69 70void FuncAdapterExit(const UsbSession *session) 71{ 72 (void)session; 73 OsalSemDestroy(&g_completeSem); 74} 75 76static bool OsDeviceCompare(HdfSListNode *listEntry, uint32_t searchKey) 77{ 78 UsbDevice *dev = reinterpret_cast<UsbDevice *>(listEntry); 79 if (dev == nullptr) { 80 HDF_LOGE("%{public}s: invalid param listEntry", __func__); 81 return false; 82 } 83 84 if ((dev->busNum == (searchKey >> BUS_OFFSET)) && (dev->devAddr == (searchKey & 0xFF))) { 85 return true; 86 } 87 88 return false; 89} 90 91static UsbDeviceHandle *OsGetDeviceHandle(UsbSession *session, uint8_t busNum, uint8_t usbAddr) 92{ 93 if (session == nullptr) { 94 HDF_LOGE("%{public}s: invalid param session", __func__); 95 return nullptr; 96 } 97 UsbDeviceHandle *handle = nullptr; 98 OsalMutexLock(&session->lock); 99 UsbDevice *dev = reinterpret_cast<UsbDevice *>( 100 HdfSListSearch(&session->usbDevs, (busNum << BUS_OFFSET) | usbAddr, OsDeviceCompare)); 101 if (dev != nullptr) { 102 handle = dev->devHandle; 103 AdapterAtomicInc(&dev->refcnt); 104 } 105 OsalMutexUnlock(&session->lock); 106 107 return handle; 108} 109 110static UsbDeviceHandle *OsCallocDeviceHandle(void) 111{ 112 UsbDeviceHandle *usbHandle = static_cast<UsbDeviceHandle *>(RawUsbMemCalloc(sizeof(UsbDeviceHandle))); 113 if (usbHandle == nullptr) { 114 HDF_LOGE("%{public}s: allocate g_usbHandle failed", __func__); 115 return nullptr; 116 } 117 OsalMutexInit(&usbHandle->lock); 118 119 return usbHandle; 120} 121 122static UsbDevice *OsAllocDevice(UsbSession *session, UsbDeviceHandle *handle) 123{ 124 UsbDevice *dev = static_cast<UsbDevice *>(RawUsbMemCalloc(sizeof(UsbDevice))); 125 if (dev == nullptr) { 126 HDF_LOGE("%{public}s: RawUsbMemCalloc failed", __func__); 127 return nullptr; 128 } 129 130 dev->session = session; 131 dev->devHandle = handle; 132 RawRequestListInit(dev); 133 handle->dev = dev; 134 135 return dev; 136} 137static int32_t OsReadDescriptors(UsbDevice *dev) 138{ 139 dev->descriptors = static_cast<uint8_t *>(RawUsbMemAlloc(DESCRIPTORSLENGTH)); 140 dev->descriptorsLength = DESCRIPTORSLENGTH; 141 if (memcpy_s(dev->descriptors, dev->descriptorsLength, g_buf.data(), DESCRIPTORSLENGTH) != EOK) { 142 HDF_LOGE("%{public}s: memcpy_s failed", __func__); 143 return HDF_FAILURE; 144 } 145 return HDF_SUCCESS; 146} 147 148static int32_t OsParseConfigDescriptors(UsbDevice *dev) 149{ 150 UsbDeviceDescriptor *deviceDesc = static_cast<UsbDeviceDescriptor *>(dev->descriptors); 151 uint8_t numConfigs = deviceDesc->bNumConfigurations; 152 if (numConfigs == 0) { 153 return HDF_SUCCESS; 154 } 155 dev->configDescriptors = 156 static_cast<UsbDeviceConfigDescriptor *>(RawUsbMemAlloc(numConfigs * sizeof(UsbDeviceConfigDescriptor))); 157 if (dev->configDescriptors == nullptr) { 158 HDF_LOGE("%{public}s: RawUsbMemAlloc failed.", __func__); 159 return HDF_ERR_MALLOC_FAIL; 160 } 161 uint8_t *buffer = static_cast<uint8_t *>(dev->descriptors) + USB_DDK_DT_DEVICE_SIZE; 162 size_t descLen = dev->descriptorsLength - USB_DDK_DT_DEVICE_SIZE; 163 for (uint8_t i = 0; i < numConfigs; i++) { 164 if (descLen < USB_DDK_DT_CONFIG_SIZE) { 165 HDF_LOGE("%{public}s: read %{public}zu", __func__, descLen); 166 RawUsbMemFree(dev->configDescriptors); 167 return HDF_ERR_IO; 168 } 169 UsbConfigDescriptor *configDesc = reinterpret_cast<UsbConfigDescriptor *>(buffer); 170 if ((configDesc->bDescriptorType != USB_DDK_DT_CONFIG) || (configDesc->bLength < USB_DDK_DT_CONFIG_SIZE)) { 171 HDF_LOGE("%{public}s: config desc error: type 0x%{public}02x, length %{public}u", 172 __func__, configDesc->bDescriptorType, configDesc->bLength); 173 RawUsbMemFree(dev->configDescriptors); 174 return HDF_ERR_IO; 175 } 176 uint16_t configLen = LE16_TO_CPU(configDesc->wTotalLength); 177 if (configLen < USB_DDK_DT_CONFIG_SIZE) { 178 HDF_LOGE("invalid wTotalLength value %{public}u", configLen); 179 RawUsbMemFree(dev->configDescriptors); 180 return HDF_ERR_IO; 181 } 182 if (configLen > descLen) { 183 HDF_LOGI("%{public}s: read %{public}zu/%{public}u", __func__, descLen, configLen); 184 configLen = static_cast<uint16_t>(descLen); 185 } 186 dev->configDescriptors[i].desc = configDesc; 187 dev->configDescriptors[i].actualLen = configLen; 188 buffer += configLen; 189 descLen -= configLen; 190 } 191 return HDF_SUCCESS; 192} 193 194static int32_t OsInitDevice(UsbDevice *dev, uint8_t busNum, uint8_t devAddr) 195{ 196 UsbDeviceHandle *devHandle = dev->devHandle; 197 dev->busNum = busNum; 198 dev->devAddr = devAddr; 199 devHandle->caps = CAPS; 200 dev->descriptorsLength = 0; 201 202 int32_t ret = OsReadDescriptors(dev); 203 if (ret != HDF_SUCCESS) { 204 HDF_LOGE("%{public}s: OsReadDescriptors failed ret = %{pubilc}d", __func__, ret); 205 return ret; 206 } 207 ret = OsParseConfigDescriptors(dev); 208 if (ret != HDF_SUCCESS) { 209 HDF_LOGE("%{public}s: OsParseConfigDescriptors failed ret = %{pubilc}d", __func__, ret); 210 return ret; 211 } 212 ret = memcpy_s(&dev->deviceDescriptor, sizeof(UsbDeviceDescriptor), dev->descriptors, USB_DDK_DT_DEVICE_SIZE); 213 if (ret != EOK) { 214 HDF_LOGE("%{public}s: memcpy_s failed ret = %{public}d", __func__, ret); 215 ret = HDF_ERR_IO; 216 } 217 return ret; 218} 219 220UsbDeviceHandle *FuncAdapterOpenDevice(UsbSession *session, uint8_t busNum, uint8_t usbAddr) 221{ 222 g_usbHandle = OsGetDeviceHandle(session, busNum, usbAddr); 223 if (g_usbHandle != nullptr) { 224 return g_usbHandle; 225 } 226 227 g_usbHandle = OsCallocDeviceHandle(); 228 if (g_usbHandle == nullptr) { 229 return nullptr; 230 } 231 232 g_dev = OsAllocDevice(session, g_usbHandle); 233 if (g_dev == nullptr) { 234 OsalMutexDestroy(&g_usbHandle->lock); 235 RawUsbMemFree(g_usbHandle); 236 return nullptr; 237 } 238 239 int32_t ret = OsInitDevice(g_dev, busNum, usbAddr); 240 if (ret != HDF_SUCCESS) { 241 RawUsbMemFree(g_dev); 242 return nullptr; 243 } 244 245 OsalAtomicSet(&g_dev->refcnt, 1); 246 // add the new device to the device list on session 247 OsalMutexLock(&session->lock); 248 HdfSListAdd(&session->usbDevs, &g_dev->list); 249 OsalMutexUnlock(&session->lock); 250 (void)FillUsbDeviceHandle(g_usbHandle); 251 return g_usbHandle; 252} 253 254void FuncAdapterCloseDevice(UsbDeviceHandle *handle) 255{ 256 struct UsbDevice *dev = NULL; 257 258 if ((handle == NULL) || (handle->dev == NULL)) { 259 HDF_LOGE("%{public}s:%{public}d invalid param", __func__, __LINE__); 260 return; 261 } 262 263 dev = handle->dev; 264 if (AdapterAtomicDec(&dev->refcnt) > 0) { 265 return; 266 } 267 268 OsalMutexLock(&dev->session->lock); 269 HdfSListRemove(&dev->session->usbDevs, &dev->list); 270 OsalMutexUnlock(&dev->session->lock); 271 272 if (dev->configDescriptors) { 273 RawUsbMemFree(dev->configDescriptors); 274 } 275 if (dev->descriptors) { 276 RawUsbMemFree(dev->descriptors); 277 } 278 RawUsbMemFree(dev); 279 OsalMutexDestroy(&handle->lock); 280 RawUsbMemFree(handle); 281} 282 283int32_t FuncAdapterGetConfigDescriptor(const UsbDevice *dev, uint8_t configIndex, void *buffer, size_t len) 284{ 285 UsbDeviceConfigDescriptor *config = nullptr; 286 uint8_t i; 287 if (dev == nullptr || buffer == nullptr || (configIndex > dev->deviceDescriptor.bNumConfigurations)) { 288 return HDF_ERR_INVALID_PARAM; 289 } 290 configIndex = 1; 291 for (i = 0; i < dev->deviceDescriptor.bNumConfigurations; i++) { 292 if (configIndex == dev->configDescriptors[i].desc->bConfigurationValue) { 293 config = &dev->configDescriptors[i]; 294 break; 295 } 296 } 297 298 if (config == nullptr) { 299 HDF_LOGE("%{public}s: config is null", __func__); 300 return HDF_ERR_BAD_FD; 301 } 302 int32_t lenTmp = MIN(static_cast<int32_t>(len), static_cast<int32_t>(config->actualLen)); 303 if (memcpy_s(buffer, lenTmp, config->desc, lenTmp) != EOK) { 304 HDF_LOGE("%{public}s: memcpy_s failed", __func__); 305 return HDF_ERR_IO; 306 } 307 return lenTmp; 308} 309 310static int32_t OsGetActiveConfig(UsbDevice *dev, int32_t fd) 311{ 312 (void)fd; 313 if (dev == nullptr) { 314 HDF_LOGE("%{public}s: invalid param dev", __func__); 315 return HDF_ERR_INVALID_PARAM; 316 } 317 dev->activeConfig = 0; 318 return HDF_SUCCESS; 319} 320 321int32_t FuncAdapterGetConfiguration(const UsbDeviceHandle *handle, uint8_t *activeConfig) 322{ 323 if (handle == nullptr || activeConfig == nullptr || handle->dev == nullptr) { 324 HDF_LOGE("%{public}s: invalid param", __func__); 325 return HDF_ERR_INVALID_PARAM; 326 } 327 328 int32_t ret = OsGetActiveConfig(handle->dev, handle->fd); 329 if (ret != HDF_SUCCESS) { 330 return ret; 331 } 332 333 *activeConfig = handle->dev->activeConfig; 334 if (*activeConfig == 0) { 335 HDF_LOGI("%{public}s: activeConfig is zero", __func__); 336 } 337 return HDF_SUCCESS; 338} 339 340int32_t FuncAdapterSetConfiguration(UsbDeviceHandle *handle, int32_t activeConfig) 341{ 342 if (handle == nullptr || handle->dev == nullptr) { 343 HDF_LOGE("%{public}s: invalid param", __func__); 344 return HDF_ERR_INVALID_PARAM; 345 } 346 handle->dev->activeConfig = ACTIVE_NUM; 347 return HDF_SUCCESS; 348} 349 350int32_t FuncAdapterClaimInterface(const UsbDeviceHandle *handle, uint32_t interfaceNumber) 351{ 352 (void)handle; 353 (void)interfaceNumber; 354 return HDF_SUCCESS; 355} 356 357int32_t FuncAdapterReleaseInterface(const UsbDeviceHandle *handle, uint32_t interfaceNumber) 358{ 359 (void)handle; 360 (void)interfaceNumber; 361 return HDF_SUCCESS; 362} 363 364int32_t FuncAdapterSetInterface(const UsbDeviceHandle *handle, uint8_t interface, uint8_t altSetting) 365{ 366 (void)handle; 367 (void)interface; 368 (void)altSetting; 369 return HDF_SUCCESS; 370} 371 372int32_t FuncAdapterClearHalt(const UsbDeviceHandle *handle, uint32_t endPoint) 373{ 374 (void)handle; 375 (void)endPoint; 376 return HDF_SUCCESS; 377} 378 379int32_t FuncAdapterResetDevice(const UsbDeviceHandle *handle) 380{ 381 (void)handle; 382 return HDF_SUCCESS; 383} 384 385UsbHostRequest *FuncAdapterAllocRequest(const UsbDeviceHandle *handle, int32_t isoPackets, size_t len) 386{ 387 void *memBuf = nullptr; 388 UsbHostRequest *request; 389 390 if (handle == nullptr) { 391 HDF_LOGE("%{public}s: invalid param", __func__); 392 return nullptr; 393 } 394 size_t allocSize = sizeof(UsbHostRequest) + (sizeof(UsbIsoPacketDesc) * static_cast<size_t>(isoPackets)) + 395 (sizeof(unsigned char) * len); 396 memBuf = RawUsbMemCalloc(allocSize); 397 if (memBuf == nullptr) { 398 HDF_LOGE("%{public}s: alloc UsbHostRequest failed", __func__); 399 return nullptr; 400 } 401 request = static_cast<UsbHostRequest *>(memBuf); 402 g_sprq = request; 403 request->numIsoPackets = isoPackets; 404 request->buffer = static_cast<unsigned char *>(memBuf) + allocSize - len; 405 request->bufLen = len; 406 request->bulkUrb = RawUsbMemCalloc(sizeof(UsbAdapterUrb)); 407 if (request->bulkUrb == nullptr) { 408 HDF_LOGE("%{public}s RawUsbMemAlloc fail", __func__); 409 RawUsbMemFree(memBuf); 410 return nullptr; 411 } 412 request->urbs = request->bulkUrb; 413 return request; 414} 415 416int32_t FuncAdapterFreeRequest(UsbHostRequest *request) 417{ 418 if (request == nullptr) { 419 HDF_LOGE("%{public}s: invalid param", __func__); 420 return HDF_ERR_INVALID_PARAM; 421 } 422 if (request->bulkUrb != nullptr) { 423 RawUsbMemFree(request->bulkUrb); 424 request->urbs = nullptr; 425 } 426 if (request != nullptr) { 427 RawUsbMemFree(request); 428 request = nullptr; 429 } 430 return HDF_SUCCESS; 431} 432 433int32_t FuncAdapterSubmitRequest(UsbHostRequest *request) 434{ 435 if (g_sprq == nullptr) { 436 HDF_LOGE("%{public}s: g_sprq nullptr", __func__); 437 return HDF_ERR_INVALID_PARAM; 438 } 439 g_sprq->status = request->status; 440 OsalSemPost(&g_completeSem); 441 return HDF_SUCCESS; 442} 443 444int32_t FuncAdapterCancelRequest(UsbHostRequest * const request) 445{ 446 if (!((request->requestType == USB_REQUEST_TYPE_BULK) && (request->reqStatus == USB_REQUEST_ERROR))) { 447 request->reqStatus = USB_REQUEST_CANCELLED; 448 } 449 return HDF_SUCCESS; 450} 451 452static int32_t RequestCompletion(UsbHostRequest *request, UsbRequestStatus status) 453{ 454 if (request == nullptr) { 455 HDF_LOGE("%{public}s: request is nullptr!", __func__); 456 return HDF_ERR_INVALID_PARAM; 457 } 458 request->status = status; 459 int32_t ret = memset_s(request->buffer, request->bufLen, ACTIVE_NUM, request->bufLen); 460 if (ret != EOK) { 461 HDF_LOGE("%{public}s: memset_s failed", __func__); 462 return ret; 463 } 464 if (request->callback) { 465 request->callback(static_cast<void *>(request)); 466 } 467 return HDF_SUCCESS; 468} 469 470int32_t FuncAdapterUrbCompleteHandle(const UsbDeviceHandle *devHandle) 471{ 472 uint32_t waitTime; 473 if (devHandle == nullptr) { 474 HDF_LOGE("%{public}s: invalid param", __func__); 475 return HDF_ERR_INVALID_PARAM; 476 } 477 waitTime = SEM_WAIT_FOREVER; 478 (void)OsalSemWait(&g_completeSem, waitTime); 479 if (g_sprq == nullptr) { 480 return HDF_SUCCESS; 481 } 482 483 UsbRequestStatus status = USB_REQUEST_COMPLETED; 484 if (g_sprq->length <= BULK_LEN) { 485 g_sprq->actualLength = ACTIVE_NUM; 486 } else { 487 g_sprq->actualLength = BULK_LEN; 488 } 489 return RequestCompletion(g_sprq, status); 490} 491