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 /** CDC ACM 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_cdc_acm.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_cdc_acm_command PORTABLE C */
37 /* 6.3.0 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function will send a command to the ACM device. The command */
45 /* can be one of the following : */
46 /* SET_CONTROL */
47 /* SET_LINE */
48 /* SEND_BREAK */
49 /* */
50 /* */
51 /* INPUT */
52 /* */
53 /* acm Pointer to acm class */
54 /* command command value */
55 /* value value to be sent in the */
56 /* command request */
57 /* data_buffer buffer to be sent */
58 /* data_length length of the buffer to send */
59 /* */
60 /* */
61 /* OUTPUT */
62 /* */
63 /* Completion Status */
64 /* */
65 /* CALLS */
66 /* */
67 /* _ux_host_stack_transfer_request Process transfer request */
68 /* _ux_host_semaphore_get Get semaphore */
69 /* */
70 /* CALLED BY */
71 /* */
72 /* Application */
73 /* */
74 /* RELEASE HISTORY */
75 /* */
76 /* DATE NAME DESCRIPTION */
77 /* */
78 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
79 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
80 /* resulting in version 6.1 */
81 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
82 /* added standalone support, */
83 /* resulting in version 6.1.10 */
84 /* 10-31-2023 Yajun xia Modified comment(s), */
85 /* resulting in version 6.3.0 */
86 /* */
87 /**************************************************************************/
_ux_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM * cdc_acm,ULONG command,ULONG value,UCHAR * data_buffer,ULONG data_length)88 UINT _ux_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM *cdc_acm, ULONG command,
89 ULONG value, UCHAR *data_buffer, ULONG data_length)
90 {
91
92 #if defined(UX_HOST_STANDALONE)
93 UX_INTERRUPT_SAVE_AREA
94 UX_DEVICE *device;
95 #endif
96
97 UX_ENDPOINT *control_endpoint;
98 UX_TRANSFER *transfer_request;
99 UINT status;
100 ULONG request_direction;
101
102
103 /* We need to get the default control endpoint transfer request pointer. */
104 control_endpoint = &cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_control_endpoint;
105 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
106
107 /* Check the direction of the command. */
108 switch (command)
109 {
110
111 case UX_HOST_CLASS_CDC_ACM_REQ_SEND_ENCAPSULATED_COMMAND :
112 /* Fall through. */
113 case UX_HOST_CLASS_CDC_ACM_REQ_SET_COMM_FEATURE :
114 /* Fall through. */
115 case UX_HOST_CLASS_CDC_ACM_REQ_CLEAR_COMM_FEATURE :
116 /* Fall through. */
117 case UX_HOST_CLASS_CDC_ACM_REQ_SET_AUX_LINE_STATE :
118 /* Fall through. */
119 case UX_HOST_CLASS_CDC_ACM_REQ_SET_HOOK_STATE :
120 /* Fall through. */
121 case UX_HOST_CLASS_CDC_ACM_REQ_PULSE_SETUP :
122 /* Fall through. */
123 case UX_HOST_CLASS_CDC_ACM_REQ_SEND_PULSE :
124 /* Fall through. */
125 case UX_HOST_CLASS_CDC_ACM_REQ_SET_PUSLE_TIME :
126 /* Fall through. */
127 case UX_HOST_CLASS_CDC_ACM_REQ_RING_AUX_JACK :
128 /* Fall through. */
129 case UX_HOST_CLASS_CDC_ACM_REQ_SET_LINE_CODING :
130 /* Fall through. */
131 case UX_HOST_CLASS_CDC_ACM_REQ_SET_LINE_STATE :
132 /* Fall through. */
133 case UX_HOST_CLASS_CDC_ACM_REQ_SEND_BREAK :
134 /* Fall through. */
135 case UX_HOST_CLASS_CDC_ACM_REQ_SET_RINGER_PARMS :
136 /* Fall through. */
137 case UX_HOST_CLASS_CDC_ACM_REQ_SET_OPERATION_PARMS :
138 /* Fall through. */
139 case UX_HOST_CLASS_CDC_ACM_REQ_SET_LINE_PARMS :
140
141 /* Direction is out */
142 request_direction = UX_REQUEST_OUT;
143 break;
144
145
146 case UX_HOST_CLASS_CDC_ACM_REQ_GET_ENCAPSULATED_COMMAND :
147 /* Fall through. */
148 case UX_HOST_CLASS_CDC_ACM_REQ_GET_COMM_FEATURE :
149 /* Fall through. */
150 case UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING :
151 /* Fall through. */
152 case UX_HOST_CLASS_CDC_ACM_REQ_GET_RINGER_PARMS :
153 /* Fall through. */
154 case UX_HOST_CLASS_CDC_ACM_REQ_GET_OPERATION_PARMS :
155 /* Fall through. */
156 case UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_PARMS :
157
158 /* Direction is in */
159 request_direction = UX_REQUEST_IN;
160 break;
161
162
163 default :
164
165 return(UX_ERROR);
166
167 }
168
169 #if defined(UX_HOST_STANDALONE)
170
171 /* Get device instance. */
172 device = cdc_acm -> ux_host_class_cdc_acm_device;
173
174 /* Check device EP0 transfer lock flag. */
175 UX_DISABLE
176 if (device -> ux_device_flags & UX_DEVICE_FLAG_LOCK)
177 {
178 UX_RESTORE
179 return(UX_STATE_LOCK);
180 }
181
182 /* Lock the device for EP0 transfer. */
183 device -> ux_device_flags |= UX_DEVICE_FLAG_LOCK;
184 transfer_request -> ux_transfer_request_flags |= UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK;
185 UX_RESTORE
186 #else
187
188 /* Protect the control endpoint semaphore here. It will be unprotected in the
189 transfer request function. */
190 status = _ux_host_semaphore_get(&cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
191
192 /* Check for status. */
193 if (status != UX_SUCCESS)
194
195 /* Something went wrong. */
196 return(status);
197 #endif
198
199 /* Create a transfer_request for the request. */
200 transfer_request -> ux_transfer_request_data_pointer = data_buffer;
201 transfer_request -> ux_transfer_request_requested_length = data_length;
202 transfer_request -> ux_transfer_request_function = command;
203 transfer_request -> ux_transfer_request_type = request_direction | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
204 transfer_request -> ux_transfer_request_value = value;
205 transfer_request -> ux_transfer_request_index = cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceNumber;
206
207 /* Send request to HCD layer. */
208 status = _ux_host_stack_transfer_request(transfer_request);
209
210 /* Return completion status. */
211 return(status);
212 }
213
214
215 /**************************************************************************/
216 /* */
217 /* FUNCTION RELEASE */
218 /* */
219 /* _uxe_host_class_cdc_acm_command PORTABLE C */
220 /* 6.3.0 */
221 /* AUTHOR */
222 /* */
223 /* Chaoqiong Xiao, Microsoft Corporation */
224 /* */
225 /* DESCRIPTION */
226 /* */
227 /* This function checks errors in CDC ACM command function call. */
228 /* */
229 /* INPUT */
230 /* */
231 /* cdc_acm Pointer to CDC ACM class */
232 /* command command value */
233 /* value value to be sent in the */
234 /* command request */
235 /* data_buffer buffer to be sent */
236 /* data_length length of the buffer to send */
237 /* */
238 /* OUTPUT */
239 /* */
240 /* Status */
241 /* */
242 /* CALLS */
243 /* */
244 /* _ux_host_class_cdc_acm_command Send CDC ACM request */
245 /* */
246 /* CALLED BY */
247 /* */
248 /* Application */
249 /* CDC ACM Class */
250 /* */
251 /* RELEASE HISTORY */
252 /* */
253 /* DATE NAME DESCRIPTION */
254 /* */
255 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
256 /* */
257 /**************************************************************************/
_uxe_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM * cdc_acm,ULONG command,ULONG value,UCHAR * data_buffer,ULONG data_length)258 UINT _uxe_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM *cdc_acm, ULONG command,
259 ULONG value, UCHAR *data_buffer, ULONG data_length)
260 {
261
262 /* Sanity check. */
263 if (cdc_acm == UX_NULL)
264 return(UX_INVALID_PARAMETER);
265
266 /* Invoke CDC ACM command send function. */
267 return(_ux_host_class_cdc_acm_command(cdc_acm, command, value, data_buffer, data_length));
268 }
269