GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_device_classes/src/ux_device_class_hid_control_request.c Lines: 44 44 100.0 %
Date: 2026-03-06 18:57:10 Branches: 15 15 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** USBX Component                                                        */
17
/**                                                                       */
18
/**   Device HID Class                                                    */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
#define UX_SOURCE_CODE
24
25
26
/* Include necessary system files.  */
27
28
#include "ux_api.h"
29
#include "ux_device_class_hid.h"
30
#include "ux_device_stack.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _ux_device_class_hid_control_request                PORTABLE C      */
38
/*                                                           6.1.12       */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Chaoqiong Xiao, Microsoft Corporation                               */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function manages the based sent by the host on the control     */
46
/*    endpoints with a CLASS or VENDOR SPECIFIC type.                     */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    command                              Pointer to hid command         */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    None                                                                */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    _ux_device_stack_transfer_request     Transfer request              */
59
/*    _ux_device_class_hid_report_get       Process Get_Report request    */
60
/*    _ux_device_class_hid_report_set       Process Set_Report request    */
61
/*    _ux_device_class_hid_descriptor_send  Send requested descriptor     */
62
/*                                                                        */
63
/*  CALLED BY                                                             */
64
/*                                                                        */
65
/*    HID Class                                                           */
66
/*                                                                        */
67
/**************************************************************************/
68
848
UINT  _ux_device_class_hid_control_request(UX_SLAVE_CLASS_COMMAND *command)
69
{
70
71
UX_SLAVE_TRANSFER           *transfer_request;
72
UX_SLAVE_DEVICE             *device;
73
UX_SLAVE_CLASS              *class_ptr;
74
ULONG                       request;
75
ULONG                       request_value;
76
ULONG                       request_index;
77
ULONG                       request_length;
78
ULONG                       descriptor_type;
79
UCHAR                       duration;
80
UX_SLAVE_CLASS_HID          *hid;
81
82
    /* Get the pointer to the device.  */
83
848
    device =  &_ux_system_slave -> ux_system_slave_device;
84
85
    /* Get the pointer to the transfer request associated with the control endpoint.  */
86
848
    transfer_request =  &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
87
88
    /* Extract all necessary fields of the request.  */
89
848
    request =  *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST);
90
848
    request_value  =   _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE);
91
848
    request_index  =   _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_INDEX);
92
848
    request_length =   _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH);
93
94
    /* Duration - upper byte of wValue.  */
95
848
    duration       =   *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE + 1);
96
97
     /* Get the class container.  */
98
848
    class_ptr =  command -> ux_slave_class_command_class_ptr;
99
100
    /* Get the storage instance from this class container.  */
101
848
    hid =  (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance;
102
103
    /* Here we proceed only the standard request we know of at the device level.  */
104

848
    switch (request)
105
    {
106
107
17
        case UX_DEVICE_CLASS_HID_COMMAND_GET_REPORT:
108
109
            /* Send the requested report to the host.  */
110
17
            _ux_device_class_hid_report_get(hid, request_value, request_index, request_length);
111
17
            break;
112
113
164
        case UX_DEVICE_CLASS_HID_COMMAND_SET_REPORT:
114
115
            /* Extract the descriptor type.  */
116
164
            descriptor_type =  (request_value & 0xff00) >> 8;
117
118
            /* Get the requested report from the host.  */
119
164
            _ux_device_class_hid_report_set(hid, descriptor_type, request_index, request_length);
120
164
            break;
121
122
460
        case UX_GET_DESCRIPTOR:
123
124
            /* Send the requested descriptor to the host.  */
125
460
            _ux_device_class_hid_descriptor_send(hid, request_value, request_index, request_length);
126
460
            break;
127
128
203
        case UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE:
129
        case UX_DEVICE_CLASS_HID_COMMAND_SET_IDLE:
130
131
            /* Ignore Report ID for now.  */
132
133
203
            if (request == UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE)
134
            {
135
136
                /* Send the idle rate.  */
137
7
                *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)hid -> ux_device_class_hid_event_idle_rate;
138
7
                _ux_device_stack_transfer_request(transfer_request, 1, request_length);
139
            }
140
            else
141
            {
142
143
                /* Accept the idle rate if it changes.  */
144
196
                if ((UCHAR)hid -> ux_device_class_hid_event_idle_rate != duration)
145
                {
146
147
6
                    hid -> ux_device_class_hid_event_idle_rate = duration;
148
6
                    if (duration == 0)
149
                    {
150
151
                        /* No need to repeat last report, no timeout.  */
152
3
                        hid -> ux_device_class_hid_event_wait_timeout = UX_WAIT_FOREVER;
153
                    }
154
                    else
155
                    {
156
157
                        /* Calculate the timeout value.  Weighted as 4ms.  */
158
3
                        hid -> ux_device_class_hid_event_wait_timeout = (ULONG)UX_MS_TO_TICK((ULONG)duration << 2u);
159
160
                        /* Be sure to have a timeout that is not zero.  */
161
3
                        if (hid -> ux_device_class_hid_event_wait_timeout == 0)
162
1
                            hid -> ux_device_class_hid_event_wait_timeout ++;
163
164
#if defined(UX_DEVICE_STANDALONE)
165
166
                        /* Restart event checking if no transfer in progress.  */
167
                        if (hid -> ux_device_class_hid_event_state != UX_STATE_WAIT)
168
                            hid -> ux_device_class_hid_event_state = UX_STATE_RESET;
169
#else
170
171
                        /* Set an event to wake up the interrupt thread.  */
172
3
                        _ux_device_event_flags_set(&hid -> ux_device_class_hid_event_flags_group, UX_DEVICE_CLASS_HID_NEW_IDLE_RATE, UX_OR);
173
#endif
174
                    }
175
                }
176
            }
177
203
            break;
178
179
2
        case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL:
180
181
            /* Send the protocol.  */
182
2
            *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)hid -> ux_device_class_hid_protocol;
183
2
            _ux_device_stack_transfer_request(transfer_request, 1, request_length);
184
2
            break;
185
186
1
        case UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL:
187
188
            /* Accept the protocol.  */
189
1
            hid -> ux_device_class_hid_protocol = request_value;
190
1
            break;
191
192
1
        default:
193
194
            /* Unknown function. It's not handled.  */
195
1
            return(UX_ERROR);
196
    }
197
198
    /* It's handled.  */
199
847
    return(UX_SUCCESS);
200
}
201