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