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