1 #include <stdio.h>
2 #include "tx_api.h"
3 #include "ux_api.h"
4 #include "ux_system.h"
5 #include "ux_utility.h"
6 #include "ux_device_stack.h"
7 #include "ux_test.h"
8 #include "ux_host_class_printer.h"
9 #include "ux_device_class_dummy_printer.h"
10 
11 #define PORT_START 1
12 #define PORT_STATUS_PORT_POWER_BIT 8
13 
14 UCHAR _ux_device_class_printer_name[] = "_ux_device_class_printer";
15 
_ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND * command)16 static VOID _ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND *command)
17 {
18 
19 UX_SLAVE_CLASS                  *printer_class = (UX_SLAVE_CLASS *)command->ux_slave_class_command_class_ptr;
20 UX_DEVICE_CLASS_PRINTER_PARAMS  *printer_params = (UX_DEVICE_CLASS_PRINTER_PARAMS *)command->ux_slave_class_command_parameter;
21 UX_DEVICE_CLASS_PRINTER         *printer;
22 
23     printer = (UX_DEVICE_CLASS_PRINTER *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_DEVICE_CLASS_PRINTER));
24     UX_TEST_ASSERT(printer != UX_NULL);
25 
26     printer_class->ux_slave_class_instance = printer;
27 
28     /* Save parameters.  */
29     _ux_utility_memory_copy(&printer->params, printer_params, sizeof(*printer_params));
30 }
31 
_ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND * command)32 static VOID _ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
33 {
34 UX_DEVICE_CLASS_PRINTER     *printer = NULL;
35 UX_SLAVE_CLASS              *class;
36 
37 
38     /* Get the class container.  */
39     class =  command -> ux_slave_class_command_class_ptr;
40 
41     /* Get the class instance in the container.  */
42     printer = (UX_DEVICE_CLASS_PRINTER *) class -> ux_slave_class_instance;
43 
44     if (printer != UX_NULL)
45         _ux_utility_memory_free(printer);
46     return;
47 }
48 
_ux_device_class_printer_activate(UX_SLAVE_CLASS_COMMAND * command)49 static UINT _ux_device_class_printer_activate(UX_SLAVE_CLASS_COMMAND *command)
50 {
51 
52 UX_SLAVE_CLASS              *printer_class = command->ux_slave_class_command_class_ptr;
53 UX_SLAVE_INTERFACE          *interface = (UX_SLAVE_INTERFACE *)command->ux_slave_class_command_interface;
54 UX_SLAVE_ENDPOINT           *endpoint;
55 UX_DEVICE_CLASS_PRINTER     *printer;
56 UINT                        i;
57 
58     printer = (UX_DEVICE_CLASS_PRINTER *)printer_class->ux_slave_class_instance;
59     interface -> ux_slave_interface_class_instance = (VOID *)printer;
60     printer -> interface = interface;
61 
62     /* We need to get the bulk endpoints. */
63     printer -> bulk_in_endpoint = UX_NULL;
64     printer -> bulk_out_endpoint = UX_NULL;
65     endpoint = interface->ux_slave_interface_first_endpoint;
66     while (endpoint)
67     {
68         /* Is this bulk endpoint?  */
69         if (endpoint->ux_slave_endpoint_descriptor.bmAttributes == UX_BULK_ENDPOINT)
70         {
71             /* Is this endpoint IN?  */
72             if (endpoint->ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_IN)
73             {
74                 printer -> bulk_in_endpoint = endpoint;
75                 if (printer -> bulk_out_endpoint)
76                     break;
77             }
78             else
79             {
80                 printer -> bulk_out_endpoint = endpoint;
81                 if (printer -> bulk_in_endpoint)
82                     break;
83             }
84         }
85         endpoint = endpoint->ux_slave_endpoint_next_endpoint;
86     }
87     /* Endpoints must be available.  */
88     if (printer->bulk_in_endpoint == UX_NULL || printer->bulk_out_endpoint == UX_NULL)
89         return(UX_ERROR);
90     /* Invoke activate callback.  */
91     if (printer->params.instance_activate)
92     {
93         printer->params.instance_activate(printer);
94     }
95     return(UX_SUCCESS);
96 }
97 
_ux_device_class_printer_deactivate(UX_SLAVE_CLASS_COMMAND * command)98 static VOID _ux_device_class_printer_deactivate(UX_SLAVE_CLASS_COMMAND *command)
99 {
100 
101 UX_SLAVE_CLASS                  *printer_class = command->ux_slave_class_command_class_ptr;
102 UX_DEVICE_CLASS_PRINTER         *printer;
103 
104     printer = (UX_DEVICE_CLASS_PRINTER *)printer_class->ux_slave_class_instance;
105     _ux_device_stack_transfer_all_request_abort(printer->bulk_in_endpoint, UX_TRANSFER_BUS_RESET);
106     _ux_device_stack_transfer_all_request_abort(printer->bulk_out_endpoint, UX_TRANSFER_BUS_RESET);
107     if (printer->params.instance_deactivate)
108     {
109         printer->params.instance_deactivate(printer);
110     }
111 }
112 
_ux_device_class_printer_change(UX_SLAVE_CLASS_COMMAND * command)113 static VOID _ux_device_class_printer_change(UX_SLAVE_CLASS_COMMAND *command)
114 {
115     UX_TEST_ASSERT(0);
116 }
117 
_configure_index_value(ULONG index)118 static UINT _configure_index_value(ULONG index)
119 {
120 UCHAR       *descriptor;
121 ULONG       configuration_index;
122 ULONG       length;
123 UCHAR       type;
124     descriptor = _ux_system_slave->ux_system_slave_device_framework;
125     configuration_index = 0;
126     while(1)
127     {
128         length = descriptor[0];
129         type = descriptor[1];
130 
131         if (type == UX_CONFIGURATION_DESCRIPTOR_ITEM)
132         {
133             if (configuration_index == index)
134                 return(descriptor[5]);
135             /* Length is total length.  */
136             length = _ux_utility_short_get(&descriptor[2]);
137             /* Next configuration.  */
138             configuration_index ++;
139         }
140 
141         /* Next descriptor.  */
142         descriptor += length;
143     }
144 }
145 
_ux_device_class_printer_control_request(UX_SLAVE_CLASS_COMMAND * command)146 static UINT _ux_device_class_printer_control_request(UX_SLAVE_CLASS_COMMAND *command)
147 {
148 
149 UCHAR                       *setup_data;
150 UCHAR                       bmRequestType;
151 UCHAR                       bRequest;
152 USHORT                      wValue;
153 USHORT                      wIndex;
154 USHORT                      wLength;
155 UCHAR                       port_index;
156 UCHAR                       descriptor_type;
157 UCHAR                       *data_ptr;
158 UX_SLAVE_DEVICE             *device;
159 UX_SLAVE_TRANSFER           *transfer_request;
160 UX_SLAVE_CLASS              *printer_class = (UX_SLAVE_CLASS *)command->ux_slave_class_command_class_ptr;
161 UX_DEVICE_CLASS_PRINTER     *printer = (UX_DEVICE_CLASS_PRINTER *)printer_class->ux_slave_class_instance;
162 UX_SLAVE_INTERFACE          *interface=printer->interface;
163 ULONG                       length;
164 
165     /* Get the pointer to the device.  */
166     device =  &_ux_system_slave->ux_system_slave_device;
167 
168     /* Get the pointer to the transfer request associated with the control endpoint.  */
169     transfer_request =  &device->ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
170 
171     setup_data = transfer_request->ux_slave_transfer_request_setup;
172     bmRequestType = setup_data[0];
173     bRequest = setup_data[1];
174     wValue = (USHORT)_ux_utility_short_get(&setup_data[2]);
175     wIndex = (USHORT)_ux_utility_short_get(&setup_data[4]);
176     wLength = (USHORT)_ux_utility_short_get(&setup_data[6]);
177 
178     data_ptr = transfer_request->ux_slave_transfer_request_data_pointer;
179 
180     switch (bRequest)
181     {
182     case UX_HOST_CLASS_PRINTER_GET_DEVICE_ID:
183         /* Check configuration INDEX (wValue), interface (HIGH wIndex), alt (LOW wIndex).  */
184         if (_configure_index_value(wValue) != interface->ux_slave_interface_class->ux_slave_class_configuration_number ||
185             setup_data[4] != interface->ux_slave_interface_descriptor.bAlternateSetting ||
186             setup_data[5] != interface->ux_slave_interface_descriptor.bInterfaceNumber)
187             return(UX_ERROR);
188         /* Send device ID.  */
189         transfer_request->ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
190         length = UX_MIN(UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH, wLength);
191         length = UX_MIN(length, printer->params.device_id_length + 2);
192         if (length)
193         {
194             _ux_utility_short_put_big_endian(data_ptr, length - 2);
195             _ux_utility_memory_copy(data_ptr + 2, printer->params.device_id, length - 2);
196         }
197         return _ux_device_stack_transfer_request(transfer_request, length, wLength);
198 
199     case UX_HOST_CLASS_PRINTER_GET_STATUS:
200         /* Check interface number.  */
201         if (wIndex != interface->ux_slave_interface_descriptor.bInterfaceNumber)
202             return(UX_ERROR);
203         /* Send status.  */
204         transfer_request->ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
205         *data_ptr = printer->port_status;
206         return _ux_device_stack_transfer_request(transfer_request, 1, wLength);
207 
208     case UX_HOST_CLASS_PRINTER_SOFT_RESET:
209         /* Check interface number.  */
210         if (wIndex != interface->ux_slave_interface_descriptor.bInterfaceNumber)
211             return(UX_ERROR);
212         /* Execute soft reset.  */
213         _ux_device_stack_transfer_all_request_abort(printer->bulk_in_endpoint, UX_TRANSFER_BUS_RESET);
214         _ux_device_stack_transfer_all_request_abort(printer->bulk_out_endpoint, UX_TRANSFER_BUS_RESET);
215         printer->soft_reset = UX_TRUE;
216         return(UX_SUCCESS);
217 
218     default:
219 
220         UX_TEST_ASSERT(0);
221         break;
222     }
223 }
224 
_ux_device_class_printer_entry(UX_SLAVE_CLASS_COMMAND * command)225 UINT _ux_device_class_printer_entry(UX_SLAVE_CLASS_COMMAND *command)
226 {
227 
228     switch(command -> ux_slave_class_command_request)
229     {
230 
231     case UX_SLAVE_CLASS_COMMAND_INITIALIZE:
232         _ux_device_class_printer_initialize(command);
233         break;
234 
235     case UX_SLAVE_CLASS_COMMAND_UNINITIALIZE:
236         _ux_device_class_printer_uninitialize(command);
237         break;
238 
239     case UX_SLAVE_CLASS_COMMAND_QUERY:
240         /* For now, always return success. */
241         break;
242 
243     case UX_SLAVE_CLASS_COMMAND_ACTIVATE:
244         return _ux_device_class_printer_activate(command);
245 
246     case UX_SLAVE_CLASS_COMMAND_CHANGE:
247         UX_TEST_ASSERT(0);
248         break;
249 
250     case UX_SLAVE_CLASS_COMMAND_DEACTIVATE:
251         _ux_device_class_printer_deactivate(command);
252         break;
253 
254     case UX_SLAVE_CLASS_COMMAND_REQUEST:
255         return _ux_device_class_printer_control_request(command);
256 
257     default:
258         UX_TEST_ASSERT(0);
259         break;
260 
261     }
262     return(UX_SUCCESS);
263 }
264