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