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 /**   Audio 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_audio.h"
29 #include "ux_host_stack.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _ux_host_class_audio_stop                           PORTABLE C      */
37 /*                                                           6.1.12       */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function stops the audio streaming (select alt interface 0).   */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    audio                                 Pointer to audio class        */
49 /*                                                                        */
50 /*  OUTPUT                                                                */
51 /*                                                                        */
52 /*    Completion Status                                                   */
53 /*                                                                        */
54 /*  CALLS                                                                 */
55 /*                                                                        */
56 /*    _ux_host_stack_endpoint_transfer_abort                              */
57 /*                                          Abort transfer                */
58 /*    _ux_host_stack_interface_setting_select                             */
59 /*                                          Select interface              */
60 /*    _ux_host_mutex_on                     Get mutex                     */
61 /*    _ux_host_mutex_off                    Release mutex                 */
62 /*                                                                        */
63 /*  CALLED BY                                                             */
64 /*                                                                        */
65 /*    Application                                                         */
66 /*                                                                        */
67 /*  RELEASE HISTORY                                                       */
68 /*                                                                        */
69 /*    DATE              NAME                      DESCRIPTION             */
70 /*                                                                        */
71 /*  07-29-2022     Chaoqiong Xiao           Initial Version 6.1.12        */
72 /*                                                                        */
73 /**************************************************************************/
_ux_host_class_audio_stop(UX_HOST_CLASS_AUDIO * audio)74 UINT  _ux_host_class_audio_stop(UX_HOST_CLASS_AUDIO *audio)
75 {
76 
77 UINT                    status;
78 UX_CONFIGURATION        *configuration;
79 UX_INTERFACE            *interface_ptr;
80 UINT                    streaming_interface;
81 
82 
83     /* Ensure the instance is valid.  */
84     if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS)
85     {
86 
87         /* Error trap. */
88         _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN);
89 
90         /* If trace is enabled, insert this event into the trace buffer.  */
91         UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0)
92 
93         return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
94     }
95 
96     /* Protect thread reentry to this instance.  */
97     _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex);
98 
99     /* Get the interface number of the audio streaming interface.  */
100     streaming_interface =  audio -> ux_host_class_audio_streaming_interface -> ux_interface_descriptor.bInterfaceNumber;
101 
102     /* We need to abort transactions on the ISO pipes.  */
103     if (audio -> ux_host_class_audio_isochronous_endpoint != UX_NULL)
104     {
105 
106         /* Abort the iso transfer.  */
107         _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_isochronous_endpoint);
108     }
109 
110 #if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT)
111     if (audio -> ux_host_class_audio_feedback_endpoint)
112         _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_feedback_endpoint);
113 #endif
114 
115     /* We found the alternate setting for the sampling values demanded, now we need
116         to search its container.  */
117     configuration =        audio -> ux_host_class_audio_streaming_interface -> ux_interface_configuration;
118     interface_ptr =        configuration -> ux_configuration_first_interface;
119 
120     /* Scan all interfaces.  */
121     while (interface_ptr != UX_NULL)
122     {
123 
124         /* We search for both the right interface and alternate setting.  */
125         if ((interface_ptr -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) &&
126             (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0))
127         {
128 
129             /* We have found the right interface/alternate setting combination
130                The stack will select it for us.  */
131             status =  _ux_host_stack_interface_setting_select(interface_ptr);
132 
133             /* If the alternate setting for the streaming interface could be selected, we memorize it.  */
134             if (status == UX_SUCCESS)
135             {
136 
137                 /* Memorize the interface.  */
138                 audio -> ux_host_class_audio_streaming_interface =  interface_ptr;
139 
140                 /* There is no endpoint for the alternate setting 0.  */
141                 _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_isochronous_endpoint);
142                 audio -> ux_host_class_audio_isochronous_endpoint = UX_NULL;
143 #if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT)
144                 if (audio -> ux_host_class_audio_feedback_endpoint)
145                 {
146                     _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_feedback_endpoint);
147                     audio -> ux_host_class_audio_feedback_endpoint = UX_NULL;
148                 }
149 #endif
150 
151                 /* Unprotect thread reentry to this instance.  */
152                 _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
153 
154                 /* Return successful completion.  */
155                 return(UX_SUCCESS);
156             }
157         }
158 
159         /* Move to next interface.  */
160         interface_ptr =  interface_ptr -> ux_interface_next_interface;
161     }
162 
163     /* Unprotect thread reentry to this instance.  */
164     _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
165 
166     /* Return failed completion status.  */
167     return(UX_NO_ALTERNATE_SETTING);
168 }
169 
170 
171 /**************************************************************************/
172 /*                                                                        */
173 /*  FUNCTION                                               RELEASE        */
174 /*                                                                        */
175 /*    _uxe_host_class_audio_stop                          PORTABLE C      */
176 /*                                                           6.3.0        */
177 /*  AUTHOR                                                                */
178 /*                                                                        */
179 /*    Chaoqiong Xiao, Microsoft Corporation                               */
180 /*                                                                        */
181 /*  DESCRIPTION                                                           */
182 /*                                                                        */
183 /*    This function checks errors in audio stop function call.            */
184 /*                                                                        */
185 /*  INPUT                                                                 */
186 /*                                                                        */
187 /*    audio                                 Pointer to audio class        */
188 /*                                                                        */
189 /*  OUTPUT                                                                */
190 /*                                                                        */
191 /*    Status                                                              */
192 /*                                                                        */
193 /*  CALLS                                                                 */
194 /*                                                                        */
195 /*    _ux_host_class_audio_stop             Hook a audio stop request     */
196 /*                                                                        */
197 /*  CALLED BY                                                             */
198 /*                                                                        */
199 /*    Application                                                         */
200 /*                                                                        */
201 /*  RELEASE HISTORY                                                       */
202 /*                                                                        */
203 /*    DATE              NAME                      DESCRIPTION             */
204 /*                                                                        */
205 /*  10-31-2023     Chaoqiong Xiao           Initial Version 6.3.0         */
206 /*                                                                        */
207 /**************************************************************************/
_uxe_host_class_audio_stop(UX_HOST_CLASS_AUDIO * audio)208 UINT  _uxe_host_class_audio_stop(UX_HOST_CLASS_AUDIO *audio)
209 {
210 
211     /* Sanity check.  */
212     if (audio == UX_NULL)
213         return(UX_INVALID_PARAMETER);
214 
215     /* Invoke audio stop function.  */
216     return(_ux_host_class_audio_stop(audio));
217 }
218