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 Remote Control 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_remote_control.h"
30 #include "ux_host_stack.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _ux_host_class_hid_remote_control_activate          PORTABLE C      */
38 /*                                                           6.1.11       */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Chaoqiong Xiao, Microsoft Corporation                               */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function performs the enumeration of a HID Remote Control      */
46 /*    class.                                                              */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    command                               Pointer to command            */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    Completion Status                                                   */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _ux_host_class_hid_periodic_report_start    Start periodic report   */
59 /*    _ux_host_class_hid_report_callback_register Register callback       */
60 /*    _ux_utility_memory_allocate           Allocate memory block         */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    HID Remote Control Class                                            */
65 /*                                                                        */
66 /*  RELEASE HISTORY                                                       */
67 /*                                                                        */
68 /*    DATE              NAME                      DESCRIPTION             */
69 /*                                                                        */
70 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
71 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
72 /*                                            resulting in version 6.1    */
73 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
74 /*                                            fixed clients management,   */
75 /*                                            resulting in version 6.1.11 */
76 /*                                                                        */
77 /**************************************************************************/
_ux_host_class_hid_remote_control_activate(UX_HOST_CLASS_HID_CLIENT_COMMAND * command)78 UINT  _ux_host_class_hid_remote_control_activate(UX_HOST_CLASS_HID_CLIENT_COMMAND *command)
79 {
80 
81 UX_HOST_CLASS_HID_REPORT_CALLBACK        call_back;
82 UX_HOST_CLASS_HID                        *hid;
83 UX_HOST_CLASS_HID_CLIENT                 *hid_client;
84 UX_HOST_CLASS_HID_CLIENT_REMOTE_CONTROL  *client_remote_control;
85 UX_HOST_CLASS_HID_REMOTE_CONTROL         *remote_control_instance;
86 UINT                                     status = UX_SUCCESS;
87 
88 
89     /* Get the instance to the HID class.  */
90     hid =  command -> ux_host_class_hid_client_command_instance;
91 
92     /* Get some memory for both the HID class instance and copy of this client
93        and for the callback.  */
94     client_remote_control =  (UX_HOST_CLASS_HID_CLIENT_REMOTE_CONTROL *)
95                     _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY,
96                                 sizeof(UX_HOST_CLASS_HID_CLIENT_REMOTE_CONTROL));
97     if (client_remote_control == UX_NULL)
98         return(UX_MEMORY_INSUFFICIENT);
99 
100     /* Get client instance and client copy.  */
101     remote_control_instance = &client_remote_control -> ux_host_class_hid_client_remote_control_remote_control;
102     hid_client = &client_remote_control -> ux_host_class_hid_client_remote_control_client;
103     _ux_utility_memory_copy(hid_client, hid -> ux_host_class_hid_client, sizeof(UX_HOST_CLASS_HID_CLIENT)); /* Use case of memcpy is verified. */
104 
105     /* Attach the remote control instance to the client instance.  */
106     hid_client -> ux_host_class_hid_client_local_instance =  (VOID *) remote_control_instance;
107 
108     /* Save the HID instance in the client instance.  */
109     remote_control_instance -> ux_host_class_hid_remote_control_hid =  hid;
110 
111     /* The instance is live now.  */
112     remote_control_instance -> ux_host_class_hid_remote_control_state =  UX_HOST_CLASS_INSTANCE_LIVE;
113 
114     /* Allocate the round-robin buffer that the remote control instance will use
115      * to store the usages as they come in.
116      * Size calculation overflow is checked near where _USAGE_ARRAY_LENGTH is defined.
117      */
118     remote_control_instance -> ux_host_class_hid_remote_control_usage_array =  (ULONG *)
119                             _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY,
120                                                         UX_HOST_CLASS_HID_REMOTE_CONTROL_USAGE_ARRAY_LENGTH*4);
121 
122     /* Check memory pointer. */
123     if (remote_control_instance -> ux_host_class_hid_remote_control_usage_array == UX_NULL)
124         status = (UX_MEMORY_INSUFFICIENT);
125 
126     /* If there is no error, go on.  */
127     if (status == UX_SUCCESS)
128     {
129 
130         /* Initialize the head and tail of this array.  */
131         remote_control_instance -> ux_host_class_hid_remote_control_usage_array_head =  remote_control_instance -> ux_host_class_hid_remote_control_usage_array;
132         remote_control_instance -> ux_host_class_hid_remote_control_usage_array_tail =  remote_control_instance -> ux_host_class_hid_remote_control_usage_array;
133 
134         /* Initialize the report callback.  */
135         call_back.ux_host_class_hid_report_callback_id =         0;
136         call_back.ux_host_class_hid_report_callback_function =   _ux_host_class_hid_remote_control_callback;
137         call_back.ux_host_class_hid_report_callback_buffer =     UX_NULL;
138         call_back.ux_host_class_hid_report_callback_flags =      UX_HOST_CLASS_HID_REPORT_INDIVIDUAL_USAGE;
139         call_back.ux_host_class_hid_report_callback_length =     0;
140 
141         /* Register the report call back when data comes in on this report.  */
142         status =  _ux_host_class_hid_report_callback_register(hid, &call_back);
143     }
144 
145     /* If there is no error, go on.  */
146     if (status == UX_SUCCESS)
147     {
148 
149         /* Start the periodic report.  */
150         status =  _ux_host_class_hid_periodic_report_start(hid);
151 
152         /* If OK, we are done.  */
153         if (status == UX_SUCCESS)
154         {
155 
156             /* Use out copy of client.  */
157             hid -> ux_host_class_hid_client = hid_client;
158 
159             /* If trace is enabled, insert this event into the trace buffer.  */
160             UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HID_REMOTE_CONTROL_ACTIVATE, hid, remote_control_instance, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
161 
162             /* If all is fine and the device is mounted, we may need to inform the application
163             if a function has been programmed in the system structure.  */
164             if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
165             {
166 
167                 /* Call system change function.  */
168                 _ux_system_host ->  ux_system_host_change_function(UX_HID_CLIENT_INSERTION, hid -> ux_host_class_hid_class, (VOID *) hid_client);
169             }
170 
171             /* We are done success.  */
172             return (UX_SUCCESS);
173         }
174     }
175 
176     /* We are here when there is error.  */
177 
178     /* Free usage array.  */
179     if (remote_control_instance -> ux_host_class_hid_remote_control_usage_array)
180         _ux_utility_memory_free(remote_control_instance -> ux_host_class_hid_remote_control_usage_array);
181 
182     /* Free instance memory.  */
183     _ux_utility_memory_free(remote_control_instance);
184 
185     /* Return completion status.  */
186     return(status);
187 }
188 
189