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: 2024-12-12 17:16:36 Branches: 8 8 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** USBX Component                                                        */
16
/**                                                                       */
17
/**   HID Mouse Client Class                                              */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
23
/* Include necessary system files.  */
24
25
#define UX_SOURCE_CODE
26
27
#include "ux_api.h"
28
#include "ux_host_class_hid.h"
29
#include "ux_host_class_hid_mouse.h"
30
#include "ux_host_stack.h"
31
32
33
#if defined(UX_HOST_STANDALONE)
34
35
#define UX_HOST_CLASS_HID_MOUSE_ENUM_START           (UX_STATE_WAIT)
36
#define UX_HOST_CLASS_HID_MOUSE_ENUM_SET_IDLE        (UX_STATE_STACK_STEP + 1)
37
#define UX_HOST_CLASS_HID_MOUSE_ENUM_PERIODIC_START  (UX_STATE_STACK_STEP + 3)
38
#define UX_HOST_CLASS_HID_MOUSE_ENUM_DONE            (UX_STATE_STACK_STEP + 4)
39
40
static inline UINT _ux_host_class_hid_mouse_activate_wait(UX_HOST_CLASS_HID_CLIENT_COMMAND *command);
41
#endif
42
43
44
/**************************************************************************/
45
/*                                                                        */
46
/*  FUNCTION                                               RELEASE        */
47
/*                                                                        */
48
/*    _ux_host_class_hid_mouse_entry                      PORTABLE C      */
49
/*                                                           6.1.10       */
50
/*  AUTHOR                                                                */
51
/*                                                                        */
52
/*    Chaoqiong Xiao, Microsoft Corporation                               */
53
/*                                                                        */
54
/*  DESCRIPTION                                                           */
55
/*                                                                        */
56
/*    This function is the entry point of the HID Mouse client. This      */
57
/*    function is called by the HID class after it has parsed a new HID   */
58
/*    report descriptor and is searching for a HID client.                */
59
/*                                                                        */
60
/*  INPUT                                                                 */
61
/*                                                                        */
62
/*    command                               Pointer to command            */
63
/*                                                                        */
64
/*  OUTPUT                                                                */
65
/*                                                                        */
66
/*    Completion Status                                                   */
67
/*                                                                        */
68
/*  CALLS                                                                 */
69
/*                                                                        */
70
/*    _ux_host_class_hid_mouse_activate     Activate HID mouse class      */
71
/*    _ux_host_class_hid_mouse_deactivate   Deactivate HID mouse class    */
72
/*                                                                        */
73
/*  CALLED BY                                                             */
74
/*                                                                        */
75
/*    Host Stack                                                          */
76
/*                                                                        */
77
/*  RELEASE HISTORY                                                       */
78
/*                                                                        */
79
/*    DATE              NAME                      DESCRIPTION             */
80
/*                                                                        */
81
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
82
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
83
/*                                            resulting in version 6.1    */
84
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
85
/*                                            added standalone support,   */
86
/*                                            resulting in version 6.1.10 */
87
/*                                                                        */
88
/**************************************************************************/
89
251
UINT  _ux_host_class_hid_mouse_entry(UX_HOST_CLASS_HID_CLIENT_COMMAND *command)
90
{
91
92
UINT        status;
93
94
95
    /* The command request will tell us we need to do here, either a enumeration
96
       query, an activation or a deactivation.  */
97

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