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_read PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function reads from the audio streaming interface. */
45 /* */
46 /* Note the request buffer should be ready for at least one packet, */
47 /* and request length is always limited to one packet size. */
48 /* */
49 /* INPUT */
50 /* */
51 /* audio Pointer to audio class */
52 /* audio_transfer_request Pointer to transfer request */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* Completion Status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _ux_host_class_audio_transfer_request Audio transfer request */
61 /* _ux_host_stack_class_instance_verify Verify instance is valid */
62 /* _ux_host_mutex_on Get mutex */
63 /* _ux_host_mutex_off Release mutex */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* Application */
68 /* Audio Class */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
75 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* 10-15-2021 Chaoqiong Xiao Modified comment(s), */
78 /* use pre-calculated value */
79 /* instead of wMaxPacketSize, */
80 /* resulting in version 6.1.9 */
81 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
82 /* refined macros names, */
83 /* resulting in version 6.1.10 */
84 /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
85 /* fixed standalone compile, */
86 /* resulting in version 6.1.11 */
87 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
88 /* refined packet size manage, */
89 /* protect reentry with mutex, */
90 /* refined transfer implement, */
91 /* fixed error return code, */
92 /* resulting in version 6.1.12 */
93 /* */
94 /**************************************************************************/
_ux_host_class_audio_read(UX_HOST_CLASS_AUDIO * audio,UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST * audio_transfer_request)95 UINT _ux_host_class_audio_read(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request)
96 {
97
98 UINT status;
99 ULONG mps;
100
101 /* If trace is enabled, insert this event into the trace buffer. */
102 UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_READ, audio, audio_transfer_request -> ux_host_class_audio_transfer_request_data_pointer,
103 audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
104
105 /* Ensure the instance is valid. */
106 if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS)
107 {
108
109 /* Error trap. */
110 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN);
111
112 /* If trace is enabled, insert this event into the trace buffer. */
113 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0)
114
115 return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
116 }
117
118 /* Protect thread reentry to this instance. */
119 _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex);
120
121 /* Ensure we have a selected interface that allows isoch transmission. */
122 if (audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0)
123 {
124
125 /* Unprotect thread reentry to this instance. */
126 _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
127
128 /* Error trap. */
129 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_AUDIO_WRONG_INTERFACE);
130
131 /* Return error status. */
132 return(UX_HOST_CLASS_AUDIO_WRONG_INTERFACE);
133 }
134
135 /* For audio in, we read packets at a time, so the transfer request size is the size of the
136 endpoint max packet size. */
137 mps = _ux_host_class_audio_max_packet_size_get(audio);
138 audio_transfer_request -> ux_host_class_audio_transfer_request_packet_size = mps;
139 audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length = mps;
140
141 /* Ask the stack to hook this transfer request to the iso ED. */
142 status = _ux_host_class_audio_transfer_request(audio, audio_transfer_request);
143
144 /* Unprotect thread reentry to this instance. */
145 _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
146
147 /* Return completion status. */
148 return(status);
149 }
150
151
152 /**************************************************************************/
153 /* */
154 /* FUNCTION RELEASE */
155 /* */
156 /* _uxe_host_class_audio_read PORTABLE C */
157 /* 6.3.0 */
158 /* AUTHOR */
159 /* */
160 /* Chaoqiong Xiao, Microsoft Corporation */
161 /* */
162 /* DESCRIPTION */
163 /* */
164 /* This function checks errors in audio read function call. */
165 /* */
166 /* INPUT */
167 /* */
168 /* audio Pointer to audio class */
169 /* audio_transfer_request Pointer to transfer request */
170 /* */
171 /* OUTPUT */
172 /* */
173 /* Status */
174 /* */
175 /* CALLS */
176 /* */
177 /* _ux_host_class_audio_read Hook a audio read request */
178 /* */
179 /* CALLED BY */
180 /* */
181 /* Application */
182 /* */
183 /* RELEASE HISTORY */
184 /* */
185 /* DATE NAME DESCRIPTION */
186 /* */
187 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
188 /* */
189 /**************************************************************************/
_uxe_host_class_audio_read(UX_HOST_CLASS_AUDIO * audio,UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST * audio_transfer_request)190 UINT _uxe_host_class_audio_read(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request)
191 {
192
193 /* Sanity checks. */
194 if ((UX_NULL == audio) || (audio_transfer_request == UX_NULL))
195 return(UX_INVALID_PARAMETER);
196
197 /* Invoke audio read function. */
198 return(_ux_host_class_audio_read(audio, audio_transfer_request));
199 }
200