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 /** USBX Component                                                        */
15 /**                                                                       */
16 /**   Device CDC Class                                                    */
17 /**                                                                       */
18 /**************************************************************************/
19 /**************************************************************************/
20 
21 #define UX_SOURCE_CODE
22 
23 
24 /* Include necessary system files.  */
25 
26 #include "ux_api.h"
27 #include "ux_device_class_cdc_acm.h"
28 #include "ux_device_stack.h"
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _ux_device_class_cdc_acm_control_request            PORTABLE C      */
36 /*                                                           6.1.12       */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Chaoqiong Xiao, Microsoft Corporation                               */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function manages the based sent by the host on the control     */
44 /*    endpoints with a CLASS or VENDOR SPECIFIC type.                     */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    cdc_acm                               Pointer to cdc_acm class      */
49 /*                                                                        */
50 /*  OUTPUT                                                                */
51 /*                                                                        */
52 /*    None                                                                */
53 /*                                                                        */
54 /*  CALLS                                                                 */
55 /*                                                                        */
56 /*    _ux_device_stack_transfer_request     Transfer request              */
57 /*                                                                        */
58 /*  CALLED BY                                                             */
59 /*                                                                        */
60 /*    CDC Class                                                           */
61 /*                                                                        */
62 /*  RELEASE HISTORY                                                       */
63 /*                                                                        */
64 /*    DATE              NAME                      DESCRIPTION             */
65 /*                                                                        */
66 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
67 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
68 /*                                            resulting in version 6.1    */
69 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
70 /*                                            fixed parameter/variable    */
71 /*                                            names conflict C++ keyword, */
72 /*                                            resulting in version 6.1.12 */
73 /*                                                                        */
74 /**************************************************************************/
_ux_device_class_cdc_acm_control_request(UX_SLAVE_CLASS_COMMAND * command)75 UINT  _ux_device_class_cdc_acm_control_request(UX_SLAVE_CLASS_COMMAND *command)
76 {
77 UX_SLAVE_CLASS_CDC_ACM                  *cdc_acm;
78 UX_SLAVE_CLASS                          *class_ptr;
79 UX_SLAVE_TRANSFER                       *transfer_request;
80 UX_SLAVE_DEVICE                         *device;
81 ULONG                                   request;
82 ULONG                                   value;
83 ULONG                                   request_length;
84 ULONG                                   transmit_length;
85 
86     /* Get the class container.  */
87     class_ptr =  command -> ux_slave_class_command_class_ptr;
88 
89     /* Get the class instance in the container.  */
90     cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class_ptr -> ux_slave_class_instance;
91 
92     /* Get the pointer to the device.  */
93     device =  &_ux_system_slave -> ux_system_slave_device;
94 
95     /* Get the pointer to the transfer request associated with the control endpoint.  */
96     transfer_request =  &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
97 
98     /* Extract all necessary fields of the request.  */
99     request =  *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST);
100 
101     /* Extract all necessary fields of the value.  */
102     value =  _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE);
103 
104     /* Pickup the request length.  */
105     request_length =   _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH);
106 
107     transmit_length = request_length ;
108 
109     /* Here we proceed only the standard request we know of at the device level.  */
110     switch (request)
111     {
112 
113         case UX_SLAVE_CLASS_CDC_ACM_SET_CONTROL_LINE_STATE:
114 
115             /* Reset current line state values. */
116             cdc_acm -> ux_slave_class_cdc_acm_data_dtr_state = 0;
117             cdc_acm -> ux_slave_class_cdc_acm_data_rts_state = 0;
118 
119             /* Get the line state parameters from the host.  DTR signal. */
120             if (value & UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_DTR)
121                 cdc_acm -> ux_slave_class_cdc_acm_data_dtr_state = UX_TRUE;
122 
123             /* Get the line state parameters from the host.  RTS signal. */
124             if (value & UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_RTS)
125                 cdc_acm -> ux_slave_class_cdc_acm_data_rts_state = UX_TRUE;
126 
127             /* If there is a parameter change function call it.  */
128             if (cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change != UX_NULL)
129             {
130 
131                 /* Invoke the application.  */
132                 cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change(cdc_acm);
133             }
134 
135             break ;
136 
137         case UX_SLAVE_CLASS_CDC_ACM_GET_LINE_CODING:
138 
139             /* Setup the length appropriately.  */
140             if (request_length >  UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_RESPONSE_SIZE)
141                 transmit_length = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_RESPONSE_SIZE;
142 
143             /* Send the line coding default parameters back to the host.  */
144             _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_BAUDRATE_STRUCT,
145                                     cdc_acm -> ux_slave_class_cdc_acm_baudrate);
146             *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_STOP_BIT_STRUCT) = cdc_acm -> ux_slave_class_cdc_acm_stop_bit;
147             *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARITY_STRUCT)   = cdc_acm -> ux_slave_class_cdc_acm_parity;
148             *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_DATA_BIT_STRUCT) = cdc_acm -> ux_slave_class_cdc_acm_data_bit;
149 
150             /* Set the phase of the transfer to data out.  */
151             transfer_request -> ux_slave_transfer_request_phase =  UX_TRANSFER_PHASE_DATA_OUT;
152 
153             /* Perform the data transfer.  */
154             _ux_device_stack_transfer_request(transfer_request, transmit_length, request_length);
155             break;
156 
157         case UX_SLAVE_CLASS_CDC_ACM_SET_LINE_CODING:
158 
159             /* Get the line coding parameters from the host.  */
160             cdc_acm -> ux_slave_class_cdc_acm_baudrate  = _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_BAUDRATE_STRUCT);
161             cdc_acm -> ux_slave_class_cdc_acm_stop_bit  = *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_STOP_BIT_STRUCT);
162             cdc_acm -> ux_slave_class_cdc_acm_parity    = *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARITY_STRUCT);
163             cdc_acm -> ux_slave_class_cdc_acm_data_bit  = *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_DATA_BIT_STRUCT);
164 
165             /* If there is a parameter change function call it.  */
166             if (cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change != UX_NULL)
167             {
168 
169                 /* Invoke the application.  */
170                 cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change(cdc_acm);
171             }
172 
173             break ;
174 
175         default:
176 
177             /* Unknown function. It's not handled.  */
178             return(UX_ERROR);
179     }
180 
181     /* It's handled.  */
182     return(UX_SUCCESS);
183 }
184 
185