Skip to content

Commit 3702d7a

Browse files
committed
feature(usb_host_hid): Added test case for the large and extra large report descriptor (disabled)
- Refactored the way how hid mock device is configured, introduced _test_hid_mock_device_mode param - Added the third hid mock device with large report descriptor (1905 bytes) to test the realloc of ctrl_xfer during usb_class_request_get_descriptor() - Added the extra large report descriptor of 32KB - Added additional run in pytest with mocked hid device with large descriptor - Added the awaiting for the ATTACH event in the hid mock device - Refined the test_app s_global_hdl concurrent access
1 parent b3fa6ce commit 3702d7a

File tree

4 files changed

+266
-106
lines changed

4 files changed

+266
-106
lines changed

host/class/hid/usb_host_hid/test_app/main/hid_mock_device.c

Lines changed: 108 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
*/
66

77
#include <stdint.h>
8+
#include "unity.h"
89
#include "tinyusb.h"
910
#include "tinyusb_default_config.h"
1011
#include "class/hid/hid_device.h"
1112
#include "hid_mock_device.h"
1213

13-
static tusb_iface_count_t tusb_iface_count = 0;
14+
static enum test_hid_mock_device _test_hid_mock_device_mode = TEST_HID_MOCK_DEVICE_MAX;
1415

1516
/************* TinyUSB descriptors ****************/
1617
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_HID * TUD_HID_DESC_LEN)
@@ -34,6 +35,31 @@ const uint8_t hid_mouse_report_descriptor[] = {
3435
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_ITF_PROTOCOL_MOUSE) )
3536
};
3637

38+
/**
39+
* Valid HID report descriptor of 1905 bytes.
40+
*
41+
* This large descriptor is intentionally sized to exceed the default 512-byte buffer
42+
* used for HID report descriptors. The size is larger than the default buffer limit,
43+
* forcing the HID Host driver to realloc the memory for CTRL transfer.
44+
*/
45+
const uint8_t hid_report_descriptor_1905B[] = {
46+
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(HID_ITF_PROTOCOL_KEYBOARD) ),
47+
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_ITF_PROTOCOL_MOUSE) ),
48+
TUD_HID_REPORT_DESC_LIGHTING(3),
49+
TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(4)),
50+
TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(5)),
51+
TUD_HID_REPORT_DESC_SYSTEM_CONTROL(HID_REPORT_ID(6)),
52+
TUD_HID_REPORT_DESC_LIGHTING(7),
53+
TUD_HID_REPORT_DESC_LIGHTING(8),
54+
TUD_HID_REPORT_DESC_LIGHTING(9),
55+
TUD_HID_REPORT_DESC_LIGHTING(10),
56+
};
57+
58+
/**
59+
* Empty HID report descriptor of 32 KB.
60+
*/
61+
const uint8_t hid_report_descriptor_32KB[32 * 1024] = {0};
62+
3763
/**
3864
* @brief String descriptor
3965
*/
@@ -69,9 +95,30 @@ static const uint8_t hid_configuration_descriptor_two_ifaces[] = {
6995
TUD_HID_DESCRIPTOR(2, 4, HID_ITF_PROTOCOL_MOUSE, sizeof(hid_mouse_report_descriptor), 0x82, 16, 10),
7096
};
7197

72-
static const uint8_t *hid_configuration_descriptor_list[TUSB_IFACE_COUNT_MAX] = {
98+
static const uint8_t hid_configuration_descriptor_report_1905B[] = {
99+
// Configuration number, interface count, string index, total length, attribute, power in mA
100+
TUD_CONFIG_DESCRIPTOR(1, CFG_TUD_HID, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
101+
102+
// Interface number, string index, boot protocol, report descriptor len, EP In address, size & polling interval
103+
TUD_HID_DESCRIPTOR(0, 4, false, sizeof(hid_report_descriptor_1905B), 0x81, 16, 10),
104+
TUD_HID_DESCRIPTOR(1, 4, false, sizeof(hid_report_descriptor_1905B), 0x82, 16, 10),
105+
};
106+
107+
static const uint8_t hid_configuration_descriptor_report_32K[] = {
108+
// Configuration number, interface count, string index, total length, attribute, power in mA
109+
TUD_CONFIG_DESCRIPTOR(1, CFG_TUD_HID, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
110+
111+
// Interface number, string index, boot protocol, report descriptor len, EP In address, size & polling interval
112+
TUD_HID_DESCRIPTOR(0, 4, false, 32 * 1024, 0x81, 16, 10),
113+
TUD_HID_DESCRIPTOR(1, 4, false, 32 * 1024, 0x82, 16, 10),
114+
};
115+
116+
117+
static const uint8_t *hid_configuration_descriptor_list[TEST_HID_MOCK_DEVICE_MAX] = {
73118
hid_configuration_descriptor_one_iface,
74-
hid_configuration_descriptor_two_ifaces
119+
hid_configuration_descriptor_two_ifaces,
120+
hid_configuration_descriptor_report_1905B,
121+
hid_configuration_descriptor_report_32K
75122
};
76123

77124
/**
@@ -99,15 +146,17 @@ static const tusb_desc_device_qualifier_t device_qualifier = {
99146
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
100147
uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance)
101148
{
102-
switch (tusb_iface_count) {
103-
case TUSB_IFACE_COUNT_ONE:
149+
switch (_test_hid_mock_device_mode) {
150+
case TEST_HID_MOCK_DEVICE_WITH_ONE_IFACE:
104151
return hid_report_descriptor;
105-
106-
case TUSB_IFACE_COUNT_TWO:
152+
case TEST_HID_MOCK_DEVICE_WITH_TWO_IFACES:
107153
return (!!instance) ? hid_mouse_report_descriptor : hid_keyboard_report_descriptor;
108-
154+
case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_1905B:
155+
return hid_report_descriptor_1905B;
156+
case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_32KB:
157+
return hid_report_descriptor_32KB;
109158
default:
110-
break;
159+
TEST_FAIL_MESSAGE("HID mock device, unhandled test mode");
111160
}
112161
return NULL;
113162
}
@@ -178,36 +227,69 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_
178227

179228
}
180229

230+
// HID Mock Device
231+
181232
/**
182-
* @brief HID Mock device start
233+
* @brief Callback for device events.
183234
*
184-
* @param[in] iface_count Interface count, when TUSB_IFACE_COUNT_ONE then there is two Interfaces, but equal (Protocol=None).
185-
* when TUSB_IFACE_COUNT_TWO then HID device mocked with two independent Interfaces (Protocol=BootKeyboard, Protocol=BootMouse).
235+
* @note
236+
* For Linux-based Hosts: Reflects the SetConfiguration() request from the Host Driver.
237+
* For Win-based Hosts: SetConfiguration() request is present only with available Class in device descriptor.
186238
*/
187-
void hid_mock_device(tusb_iface_count_t iface_count)
239+
static void hid_mock_device_event_handler(tinyusb_event_t *event, void *arg)
188240
{
189-
if (iface_count > TUSB_IFACE_COUNT_MAX) {
190-
printf("HID mock device, wrong iface_count parameter (%d)\n",
191-
iface_count);
192-
return;
241+
switch (event->id) {
242+
case TINYUSB_EVENT_ATTACHED:
243+
printf("\t --> Attached\n");
244+
break;
245+
case TINYUSB_EVENT_DETACHED:
246+
printf("\t <-- Detached\n");
247+
break;
248+
default:
249+
break;
193250
}
251+
}
252+
253+
void hid_mock_device_set_mode(const enum test_hid_mock_device mode)
254+
{
255+
// Validate test mode parameter, should be less than max value
256+
TEST_ASSERT_LESS_THAN_MESSAGE(TEST_HID_MOCK_DEVICE_MAX, mode, "HID mock device set mode, wrong test mode");
257+
_test_hid_mock_device_mode = mode;
258+
}
259+
260+
void hid_mock_device_run(void)
261+
{
262+
tinyusb_config_t tusb_cfg = TINYUSB_DEFAULT_CONFIG(hid_mock_device_event_handler);
194263

195-
// Global Interfaces count value
196-
tusb_iface_count = iface_count;
264+
TEST_ASSERT_LESS_THAN_MESSAGE(TEST_HID_MOCK_DEVICE_MAX, _test_hid_mock_device_mode, "HID mock device run, wrong test mode");
197265

198-
tinyusb_config_t tusb_cfg = TINYUSB_DEFAULT_CONFIG();
199-
tusb_cfg.descriptor.full_speed_config = hid_configuration_descriptor_list[tusb_iface_count];
266+
tusb_cfg.descriptor.full_speed_config = hid_configuration_descriptor_list[_test_hid_mock_device_mode];
200267
#if (TUD_OPT_HIGH_SPEED)
201-
tusb_cfg.descriptor.high_speed_config = hid_configuration_descriptor_list[tusb_iface_count];
268+
tusb_cfg.descriptor.high_speed_config = hid_configuration_descriptor_list[_test_hid_mock_device_mode];
202269
tusb_cfg.descriptor.qualifier = &device_qualifier;
203270
#endif // TUD_OPT_HIGH_SPEED
204271
tusb_cfg.descriptor.string = hid_string_descriptor;
205272
tusb_cfg.descriptor.string_count = sizeof(hid_string_descriptor) / sizeof(hid_string_descriptor[0]);
206273

207274
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
208275

209-
printf("HID mock device with %s has been started\n",
210-
(TUSB_IFACE_COUNT_ONE == tusb_iface_count)
211-
? "1xInterface (Protocol=None)"
212-
: "2xInterfaces (Protocol=BootKeyboard, Protocol=BootMouse)");
276+
// Print the message about the mode
277+
// Note: these messages are used in the pytest, so change them carefully
278+
switch (_test_hid_mock_device_mode) {
279+
case TEST_HID_MOCK_DEVICE_WITH_ONE_IFACE:
280+
printf("HID mock device with 1xInterface (Protocol=None) has been started\n");
281+
break;
282+
case TEST_HID_MOCK_DEVICE_WITH_TWO_IFACES:
283+
printf("HID mock device with 2xInterfaces (Protocol=BootKeyboard, Protocol=BootMouse) has been started\n");
284+
break;
285+
case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_1905B:
286+
printf("HID mock device with large report descriptor has been started\n");
287+
break;
288+
case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_32KB:
289+
printf("HID mock device with extra large report descriptor has been started\n");
290+
break;
291+
default:
292+
TEST_FAIL_MESSAGE("HID mock device, unhandled test mode");
293+
break;
294+
}
213295
}
Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6+
#include <stdint.h>
67

7-
typedef enum {
8-
TUSB_IFACE_COUNT_ONE = 0x00,
9-
TUSB_IFACE_COUNT_TWO = 0x01,
10-
TUSB_IFACE_COUNT_MAX
11-
} tusb_iface_count_t;
8+
// Define test HID mock device types
9+
enum test_hid_mock_device {
10+
TEST_HID_MOCK_DEVICE_WITH_ONE_IFACE = 0,
11+
TEST_HID_MOCK_DEVICE_WITH_TWO_IFACES,
12+
TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_1905B,
13+
TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_32KB,
14+
TEST_HID_MOCK_DEVICE_MAX,
15+
};
1216

13-
void hid_mock_device(tusb_iface_count_t iface_count);
17+
/**
18+
* @brief Set HID mock device test mode
19+
*
20+
* Note: Should be called before hid_mock_device_run()
21+
*
22+
* @param[in] mode Test mode to set
23+
*/
24+
void hid_mock_device_set_mode(const enum test_hid_mock_device mode);
25+
26+
/**
27+
* @brief Run HID mock device
28+
*
29+
* Sets up and starts the TinyUSB device stack with the selected test mode
30+
* Waits for the device to be connected
31+
*
32+
* Note: Should be called after hid_mock_device_set_mode()
33+
*/
34+
void hid_mock_device_run(void);

0 commit comments

Comments
 (0)