GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_hid_mouse_entry.c Lines: 14 14 100.0 %
Date: 2026-03-06 18:57:10 Branches: 8 8 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
/**   HID Mouse Client Class                                              */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
24
/* Include necessary system files.  */
25
26
#define UX_SOURCE_CODE
27
28
#include "ux_api.h"
29
#include "ux_host_class_hid.h"
30
#include "ux_host_class_hid_mouse.h"
31
#include "ux_host_stack.h"
32
33
34
#if defined(UX_HOST_STANDALONE)
35
36
#define UX_HOST_CLASS_HID_MOUSE_ENUM_START           (UX_STATE_WAIT)
37
#define UX_HOST_CLASS_HID_MOUSE_ENUM_SET_IDLE        (UX_STATE_STACK_STEP + 1)
38
#define UX_HOST_CLASS_HID_MOUSE_ENUM_PERIODIC_START  (UX_STATE_STACK_STEP + 3)
39
#define UX_HOST_CLASS_HID_MOUSE_ENUM_DONE            (UX_STATE_STACK_STEP + 4)
40
41
static inline UINT _ux_host_class_hid_mouse_activate_wait(UX_HOST_CLASS_HID_CLIENT_COMMAND *command);
42
#endif
43
44
45
/**************************************************************************/
46
/*                                                                        */
47
/*  FUNCTION                                               RELEASE        */
48
/*                                                                        */
49
/*    _ux_host_class_hid_mouse_entry                      PORTABLE C      */
50
/*                                                           6.1.10       */
51
/*  AUTHOR                                                                */
52
/*                                                                        */
53
/*    Chaoqiong Xiao, Microsoft Corporation                               */
54
/*                                                                        */
55
/*  DESCRIPTION                                                           */
56
/*                                                                        */
57
/*    This function is the entry point of the HID Mouse client. This      */
58
/*    function is called by the HID class after it has parsed a new HID   */
59
/*    report descriptor and is searching for a HID client.                */
60
/*                                                                        */
61
/*  INPUT                                                                 */
62
/*                                                                        */
63
/*    command                               Pointer to command            */
64
/*                                                                        */
65
/*  OUTPUT                                                                */
66
/*                                                                        */
67
/*    Completion Status                                                   */
68
/*                                                                        */
69
/*  CALLS                                                                 */
70
/*                                                                        */
71
/*    _ux_host_class_hid_mouse_activate     Activate HID mouse class      */
72
/*    _ux_host_class_hid_mouse_deactivate   Deactivate HID mouse class    */
73
/*                                                                        */
74
/*  CALLED BY                                                             */
75
/*                                                                        */
76
/*    Host Stack                                                          */
77
/*                                                                        */
78
/**************************************************************************/
79
251
UINT  _ux_host_class_hid_mouse_entry(UX_HOST_CLASS_HID_CLIENT_COMMAND *command)
80
{
81
82
UINT        status;
83
84
85
    /* The command request will tell us we need to do here, either a enumeration
86
       query, an activation or a deactivation.  */
87

251
    switch (command -> ux_host_class_hid_client_command_request)
88
    {
89
90
91
145
    case UX_HOST_CLASS_COMMAND_QUERY:
92
93
        /* The query command is used to let the HID class know if we want to own
94
           this device or not.  */
95
145
        if ((command -> ux_host_class_hid_client_command_page == UX_HOST_CLASS_HID_PAGE_GENERIC_DESKTOP_CONTROLS) &&
96
136
            (command -> ux_host_class_hid_client_command_usage == UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOUSE))
97
47
            return(UX_SUCCESS);
98
        else
99
98
            return(UX_NO_CLASS_MATCH);
100
101
102
47
    case UX_HOST_CLASS_COMMAND_ACTIVATE:
103
104
        /* The activate command is used by the HID class to start the HID client.  */
105
47
        status =  _ux_host_class_hid_mouse_activate(command);
106
107
        /* Return completion status.  */
108
47
        return(status);
109
110
#if defined(UX_HOST_STANDALONE)
111
    case UX_HOST_CLASS_COMMAND_ACTIVATE_WAIT:
112
        status = _ux_host_class_hid_mouse_activate_wait(command);
113
        return(status);
114
#endif
115
116
117
34
    case UX_HOST_CLASS_COMMAND_DEACTIVATE:
118
119
        /* The deactivate command is used by the HID class when it received a deactivate
120
           command from the USBX stack and there was a HID client attached to the HID instance.  */
121
34
        status =  _ux_host_class_hid_mouse_deactivate(command);
122
123
        /* Return completion status.  */
124
34
        return(status);
125
    }
126
127
    /* Return error status.  */
128
25
    return(UX_ERROR);
129
}
130
131
#if defined(UX_HOST_STANDALONE)
132
static inline UINT _ux_host_class_hid_mouse_activate_wait(UX_HOST_CLASS_HID_CLIENT_COMMAND *command)
133
{
134
135
UX_HOST_CLASS_HID                       *hid;
136
UX_HOST_CLASS_HID_CLIENT                *hid_client;
137
UX_HOST_CLASS_HID_MOUSE                 *mouse;
138
UINT                                    status;
139
UX_HOST_CLASS_HID_REPORT_CALLBACK       call_back;
140
141
    /* Get the instance to the HID class.  */
142
    hid = command -> ux_host_class_hid_client_command_instance;
143
144
    /* And of the HID client.  */
145
    hid_client = hid -> ux_host_class_hid_client;
146
147
    /* And of the mouse instance.  */
148
    mouse = (UX_HOST_CLASS_HID_MOUSE *) hid_client -> ux_host_class_hid_client_local_instance;
149
150
    /* Run states.  */
151
    switch(mouse -> ux_host_class_hid_mouse_enum_state)
152
    {
153
    case UX_HOST_CLASS_HID_MOUSE_ENUM_START:
154
        mouse -> ux_host_class_hid_mouse_enum_state = UX_HOST_CLASS_HID_MOUSE_ENUM_SET_IDLE;
155
        /* Fall through.  */
156
    case UX_HOST_CLASS_HID_MOUSE_ENUM_SET_IDLE:
157
158
        /* Run SET_IDLE states.  */
159
        status = _ux_host_class_hid_idle_set_run(hid, 0,
160
                            mouse -> ux_host_class_hid_mouse_id);
161
        if (status < UX_STATE_WAIT)
162
        {
163
            mouse -> ux_host_class_hid_mouse_status =
164
                                hid -> ux_host_class_hid_status;
165
166
            /* Set_Idle is optional, stall is accepted.  */
167
            if (mouse -> ux_host_class_hid_mouse_status == UX_TRANSFER_STALLED)
168
                mouse -> ux_host_class_hid_mouse_status = UX_SUCCESS;
169
170
            if (mouse -> ux_host_class_hid_mouse_status == UX_SUCCESS)
171
                mouse -> ux_host_class_hid_mouse_enum_state =
172
                                UX_HOST_CLASS_HID_MOUSE_ENUM_PERIODIC_START;
173
            else
174
                mouse -> ux_host_class_hid_mouse_enum_state =
175
                                UX_HOST_CLASS_HID_MOUSE_ENUM_DONE;
176
        }
177
        return(UX_STATE_WAIT);
178
179
    case UX_HOST_CLASS_HID_MOUSE_ENUM_PERIODIC_START:
180
181
        /* Set callback.  */
182
        call_back.ux_host_class_hid_report_callback_id =         mouse -> ux_host_class_hid_mouse_id;
183
        call_back.ux_host_class_hid_report_callback_function =   _ux_host_class_hid_mouse_callback;
184
        call_back.ux_host_class_hid_report_callback_buffer =     UX_NULL;
185
        call_back.ux_host_class_hid_report_callback_flags =      UX_HOST_CLASS_HID_REPORT_INDIVIDUAL_USAGE;
186
        call_back.ux_host_class_hid_report_callback_length =     0;
187
        status =  _ux_host_class_hid_report_callback_register(hid, &call_back);
188
        if (status != UX_SUCCESS)
189
        {
190
            mouse -> ux_host_class_hid_mouse_status = status;
191
            mouse -> ux_host_class_hid_mouse_enum_state =
192
                            UX_HOST_CLASS_HID_MOUSE_ENUM_DONE;
193
            break;
194
        }
195
196
        /* Start the periodic report.  */
197
        status =  _ux_host_class_hid_periodic_report_start(hid);
198
        mouse -> ux_host_class_hid_mouse_status = status;
199
200
        /* Fall through.  */
201
    case UX_HOST_CLASS_HID_MOUSE_ENUM_DONE:
202
203
        /* Anything failed, Free resources.  */
204
        if (mouse -> ux_host_class_hid_mouse_status != UX_SUCCESS)
205
        {
206
207
            /* Detach instance.  */
208
            hid_client -> ux_host_class_hid_client_local_instance = UX_NULL;
209
210
            /* Free instance.  */
211
            _ux_utility_memory_free(mouse);
212
213
            return(UX_STATE_ERROR);
214
        }
215
216
        /* The instance is live now.  */
217
        mouse -> ux_host_class_hid_mouse_state =  UX_HOST_CLASS_INSTANCE_LIVE;
218
219
        /* If all is fine and the device is mounted, we may need to inform the application
220
            if a function has been programmed in the system structure.  */
221
        if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
222
        {
223
224
            /* Call system change function.  */
225
            _ux_system_host ->  ux_system_host_change_function(UX_HID_CLIENT_INSERTION, hid -> ux_host_class_hid_class, (VOID *) hid_client);
226
        }
227
228
        /* If trace is enabled, insert this event into the trace buffer.  */
229
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HID_MOUSE_ACTIVATE, hid, mouse, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
230
231
        /* Return completion status.  */
232
        return(UX_STATE_NEXT);
233
234
    default: /* IDLE, Other states.  */
235
        return(UX_STATE_NEXT);
236
    }
237
238
    /* By default, wait.  */
239
    return(UX_STATE_WAIT);
240
}
241
#endif