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