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
18 constexpr uint32_t DESCRIPTORSLENGTH = 111;
19 constexpr uint32_t SEM_WAIT_FOREVER = 0xFFFFFFFF;
20 constexpr uint8_t ACTIVE_NUM = 1;
21 constexpr uint32_t BULK_LEN = 256;
22 constexpr uint32_t CAPS = 509;
23 constexpr uint8_t BLENGTH = 18;
24 constexpr uint16_t BCDUSB = 800;
25 constexpr uint8_t MAX_PACKET_SIZE = 9;
26 constexpr uint16_t ID_VENDOR = 8711;
27 constexpr uint16_t ID_PRODUCT = 24;
28 constexpr uint16_t BCD_DEVICE = 547;
29 constexpr uint8_t I_PRODUCT = 2;
30 constexpr uint8_t I_SERIAL_NUMBER = 3;
31 constexpr uint32_t CFG_LEN = 93;
32
33 static UsbDeviceHandle *g_usbHandle = nullptr;
34 static UsbDevice *g_dev = nullptr;
35 static UsbHostRequest *g_sprq = nullptr;
36 static OsalSem g_completeSem;
37
38 static 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
FillUsbDeviceHandle(UsbDeviceHandle * handle)48 static 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
FuncAdapterInit(const UsbSession * session)63 int32_t FuncAdapterInit(const UsbSession *session)
64 {
65 (void)session;
66 OsalSemInit(&g_completeSem, 0);
67 return HDF_SUCCESS;
68 }
69
FuncAdapterExit(const UsbSession * session)70 void FuncAdapterExit(const UsbSession *session)
71 {
72 (void)session;
73 OsalSemDestroy(&g_completeSem);
74 }
75
OsDeviceCompare(HdfSListNode * listEntry,uint32_t searchKey)76 static 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
OsGetDeviceHandle(UsbSession * session,uint8_t busNum,uint8_t usbAddr)91 static 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
OsCallocDeviceHandle(void)110 static 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
OsAllocDevice(UsbSession * session,UsbDeviceHandle * handle)122 static 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 }
OsReadDescriptors(UsbDevice * dev)137 static 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
OsParseConfigDescriptors(UsbDevice * dev)148 static 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
OsInitDevice(UsbDevice * dev,uint8_t busNum,uint8_t devAddr)194 static 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
FuncAdapterOpenDevice(UsbSession * session,uint8_t busNum,uint8_t usbAddr)220 UsbDeviceHandle *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
FuncAdapterCloseDevice(UsbDeviceHandle * handle)254 void 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
FuncAdapterGetConfigDescriptor(const UsbDevice * dev,uint8_t configIndex,void * buffer,size_t len)283 int32_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
OsGetActiveConfig(UsbDevice * dev,int32_t fd)310 static 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
FuncAdapterGetConfiguration(const UsbDeviceHandle * handle,uint8_t * activeConfig)321 int32_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
FuncAdapterSetConfiguration(UsbDeviceHandle * handle,int32_t activeConfig)340 int32_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
FuncAdapterClaimInterface(const UsbDeviceHandle * handle,uint32_t interfaceNumber)350 int32_t FuncAdapterClaimInterface(const UsbDeviceHandle *handle, uint32_t interfaceNumber)
351 {
352 (void)handle;
353 (void)interfaceNumber;
354 return HDF_SUCCESS;
355 }
356
FuncAdapterReleaseInterface(const UsbDeviceHandle * handle,uint32_t interfaceNumber)357 int32_t FuncAdapterReleaseInterface(const UsbDeviceHandle *handle, uint32_t interfaceNumber)
358 {
359 (void)handle;
360 (void)interfaceNumber;
361 return HDF_SUCCESS;
362 }
363
FuncAdapterSetInterface(const UsbDeviceHandle * handle,uint8_t interface,uint8_t altSetting)364 int32_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
FuncAdapterClearHalt(const UsbDeviceHandle * handle,uint32_t endPoint)372 int32_t FuncAdapterClearHalt(const UsbDeviceHandle *handle, uint32_t endPoint)
373 {
374 (void)handle;
375 (void)endPoint;
376 return HDF_SUCCESS;
377 }
378
FuncAdapterResetDevice(const UsbDeviceHandle * handle)379 int32_t FuncAdapterResetDevice(const UsbDeviceHandle *handle)
380 {
381 (void)handle;
382 return HDF_SUCCESS;
383 }
384
FuncAdapterAllocRequest(const UsbDeviceHandle * handle,int32_t isoPackets,size_t len)385 UsbHostRequest *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
FuncAdapterFreeRequest(UsbHostRequest * request)416 int32_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
FuncAdapterSubmitRequest(UsbHostRequest * request)433 int32_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
FuncAdapterCancelRequest(UsbHostRequest * const request)444 int32_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
RequestCompletion(UsbHostRequest * request,UsbRequestStatus status)452 static 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
FuncAdapterUrbCompleteHandle(const UsbDeviceHandle * devHandle)470 int32_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