• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     handle->dev = NULL;
280     dev = NULL;
281     OsalMutexDestroy(&handle->lock);
282     RawUsbMemFree(handle);
283     handle = NULL;
284 }
285 
FuncAdapterGetConfigDescriptor(const UsbDevice * dev,uint8_t configIndex,void * buffer,size_t len)286 int32_t FuncAdapterGetConfigDescriptor(const UsbDevice *dev, uint8_t configIndex, void *buffer, size_t len)
287 {
288     UsbDeviceConfigDescriptor *config = nullptr;
289     uint8_t i;
290     if (dev == nullptr || buffer == nullptr || (configIndex > dev->deviceDescriptor.bNumConfigurations)) {
291         return HDF_ERR_INVALID_PARAM;
292     }
293     configIndex = 1;
294     for (i = 0; i < dev->deviceDescriptor.bNumConfigurations; i++) {
295         if (configIndex == dev->configDescriptors[i].desc->bConfigurationValue) {
296             config = &dev->configDescriptors[i];
297             break;
298         }
299     }
300 
301     if (config == nullptr) {
302         HDF_LOGE("%{public}s: config is null", __func__);
303         return HDF_ERR_BAD_FD;
304     }
305     int32_t lenTmp = MIN(static_cast<int32_t>(len), static_cast<int32_t>(config->actualLen));
306     if (memcpy_s(buffer, lenTmp, config->desc, lenTmp) != EOK) {
307         HDF_LOGE("%{public}s: memcpy_s failed", __func__);
308         return HDF_ERR_IO;
309     }
310     return lenTmp;
311 }
312 
OsGetActiveConfig(UsbDevice * dev,int32_t fd)313 static int32_t OsGetActiveConfig(UsbDevice *dev, int32_t fd)
314 {
315     (void)fd;
316     if (dev == nullptr) {
317         HDF_LOGE("%{public}s: invalid param dev", __func__);
318         return HDF_ERR_INVALID_PARAM;
319     }
320     dev->activeConfig = 0;
321     return HDF_SUCCESS;
322 }
323 
FuncAdapterGetConfiguration(const UsbDeviceHandle * handle,uint8_t * activeConfig)324 int32_t FuncAdapterGetConfiguration(const UsbDeviceHandle *handle, uint8_t *activeConfig)
325 {
326     if (handle == nullptr || activeConfig == nullptr || handle->dev == nullptr) {
327         HDF_LOGE("%{public}s: invalid param", __func__);
328         return HDF_ERR_INVALID_PARAM;
329     }
330 
331     int32_t ret = OsGetActiveConfig(handle->dev, handle->fd);
332     if (ret != HDF_SUCCESS) {
333         return ret;
334     }
335 
336     *activeConfig = handle->dev->activeConfig;
337     if (*activeConfig == 0) {
338         HDF_LOGI("%{public}s: activeConfig is zero", __func__);
339     }
340     return HDF_SUCCESS;
341 }
342 
FuncAdapterSetConfiguration(UsbDeviceHandle * handle,int32_t activeConfig)343 int32_t FuncAdapterSetConfiguration(UsbDeviceHandle *handle, int32_t activeConfig)
344 {
345     if (handle == nullptr || handle->dev == nullptr) {
346         HDF_LOGE("%{public}s: invalid param", __func__);
347         return HDF_ERR_INVALID_PARAM;
348     }
349     handle->dev->activeConfig = ACTIVE_NUM;
350     return HDF_SUCCESS;
351 }
352 
FuncAdapterClaimInterface(const UsbDeviceHandle * handle,uint32_t interfaceNumber)353 int32_t FuncAdapterClaimInterface(const UsbDeviceHandle *handle, uint32_t interfaceNumber)
354 {
355     (void)handle;
356     (void)interfaceNumber;
357     return HDF_SUCCESS;
358 }
359 
FuncAdapterReleaseInterface(const UsbDeviceHandle * handle,uint32_t interfaceNumber)360 int32_t FuncAdapterReleaseInterface(const UsbDeviceHandle *handle, uint32_t interfaceNumber)
361 {
362     (void)handle;
363     (void)interfaceNumber;
364     return HDF_SUCCESS;
365 }
366 
FuncAdapterSetInterface(const UsbDeviceHandle * handle,uint8_t interface,uint8_t altSetting)367 int32_t FuncAdapterSetInterface(const UsbDeviceHandle *handle, uint8_t interface, uint8_t altSetting)
368 {
369     (void)handle;
370     (void)interface;
371     (void)altSetting;
372     return HDF_SUCCESS;
373 }
374 
FuncAdapterClearHalt(const UsbDeviceHandle * handle,uint32_t endPoint)375 int32_t FuncAdapterClearHalt(const UsbDeviceHandle *handle, uint32_t endPoint)
376 {
377     (void)handle;
378     (void)endPoint;
379     return HDF_SUCCESS;
380 }
381 
FuncAdapterResetDevice(const UsbDeviceHandle * handle)382 int32_t FuncAdapterResetDevice(const UsbDeviceHandle *handle)
383 {
384     (void)handle;
385     return HDF_SUCCESS;
386 }
387 
FuncAdapterAllocRequest(const UsbDeviceHandle * handle,int32_t isoPackets,size_t len)388 UsbHostRequest *FuncAdapterAllocRequest(const UsbDeviceHandle *handle, int32_t isoPackets, size_t len)
389 {
390     void *memBuf = nullptr;
391     UsbHostRequest *request;
392 
393     if (handle == nullptr) {
394         HDF_LOGE("%{public}s: invalid param", __func__);
395         return nullptr;
396     }
397     size_t allocSize = sizeof(UsbHostRequest) + (sizeof(UsbIsoPacketDesc) * static_cast<size_t>(isoPackets)) +
398         (sizeof(unsigned char) * len);
399     memBuf = RawUsbMemCalloc(allocSize);
400     if (memBuf == nullptr) {
401         HDF_LOGE("%{public}s: alloc UsbHostRequest failed", __func__);
402         return nullptr;
403     }
404     request = static_cast<UsbHostRequest *>(memBuf);
405     g_sprq = request;
406     request->numIsoPackets = isoPackets;
407     request->buffer = static_cast<unsigned char *>(memBuf) + allocSize - len;
408     request->bufLen = len;
409     request->bulkUrb = RawUsbMemCalloc(sizeof(UsbAdapterUrb));
410     if (request->bulkUrb == nullptr) {
411         HDF_LOGE("%{public}s RawUsbMemAlloc fail", __func__);
412         RawUsbMemFree(memBuf);
413         return nullptr;
414     }
415     request->urbs = request->bulkUrb;
416     return request;
417 }
418 
FuncAdapterFreeRequest(UsbHostRequest * request)419 int32_t FuncAdapterFreeRequest(UsbHostRequest *request)
420 {
421     if (request == nullptr) {
422         HDF_LOGE("%{public}s: invalid param", __func__);
423         return HDF_ERR_INVALID_PARAM;
424     }
425     if (request->bulkUrb != nullptr) {
426         RawUsbMemFree(request->bulkUrb);
427         request->urbs = nullptr;
428     }
429     if (request != nullptr) {
430         RawUsbMemFree(request);
431         request = nullptr;
432     }
433     return HDF_SUCCESS;
434 }
435 
FuncAdapterSubmitRequest(UsbHostRequest * request)436 int32_t FuncAdapterSubmitRequest(UsbHostRequest *request)
437 {
438     if (g_sprq == nullptr) {
439         HDF_LOGE("%{public}s: g_sprq nullptr", __func__);
440         return HDF_ERR_INVALID_PARAM;
441     }
442     g_sprq->status = request->status;
443     OsalSemPost(&g_completeSem);
444     return HDF_SUCCESS;
445 }
446 
FuncAdapterCancelRequest(UsbHostRequest * const request)447 int32_t FuncAdapterCancelRequest(UsbHostRequest * const request)
448 {
449     if (!((request->requestType == USB_REQUEST_TYPE_BULK) && (request->reqStatus == USB_REQUEST_ERROR))) {
450         request->reqStatus = USB_REQUEST_CANCELLED;
451     }
452     return HDF_SUCCESS;
453 }
454 
RequestCompletion(UsbHostRequest * request,UsbRequestStatus status)455 static int32_t RequestCompletion(UsbHostRequest *request, UsbRequestStatus status)
456 {
457     if (request == nullptr) {
458         HDF_LOGE("%{public}s: request is nullptr!", __func__);
459         return HDF_ERR_INVALID_PARAM;
460     }
461     request->status = status;
462     int32_t ret = memset_s(request->buffer, request->bufLen, ACTIVE_NUM, request->bufLen);
463     if (ret != EOK) {
464         HDF_LOGE("%{public}s: memset_s failed", __func__);
465         return ret;
466     }
467     if (request->callback) {
468         request->callback(static_cast<void *>(request));
469     }
470     return HDF_SUCCESS;
471 }
472 
FuncAdapterUrbCompleteHandle(const UsbDeviceHandle * devHandle)473 int32_t FuncAdapterUrbCompleteHandle(const UsbDeviceHandle *devHandle)
474 {
475     uint32_t waitTime;
476     if (devHandle == nullptr) {
477         HDF_LOGE("%{public}s: invalid param", __func__);
478         return HDF_ERR_INVALID_PARAM;
479     }
480     waitTime = SEM_WAIT_FOREVER;
481     (void)OsalSemWait(&g_completeSem, waitTime);
482     if (g_sprq == nullptr) {
483         return HDF_SUCCESS;
484     }
485 
486     UsbRequestStatus status = USB_REQUEST_COMPLETED;
487     if (g_sprq->length <= BULK_LEN) {
488         g_sprq->actualLength = ACTIVE_NUM;
489     } else {
490         g_sprq->actualLength = BULK_LEN;
491     }
492     return RequestCompletion(g_sprq, status);
493 }
494