1 /* This test is designed to test the simple dpump host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 
9 #include "ux_device_class_ccid.h"
10 #include "ux_device_stack.h"
11 
12 #include "ux_host_class_dummy.h"
13 
14 #include "ux_test_dcd_sim_slave.h"
15 #include "ux_test_hcd_sim_host.h"
16 
17 #include "ux_test_utility_sim.h"
18 
19 /* Define constants.  */
20 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
21 #define                             UX_DEMO_STACK_SIZE  1024
22 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
23 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
24 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
25 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
26 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
27 #define                             UX_DEMO_MEMORY_SIZE     (64*1024)
28 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
29 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
30 
31 #define                             UX_DEMO_MAX_SLOT_INDEX     (2)
32 #define                             UX_DEMO_MAX_BUSY_SLOTS     (2)
33 #if UX_SLAVE_REQUEST_DATA_MAX_LENGTH >= 1024
34 #define                             UX_DEMO_MAX_MESSAGE_LENGTH (1024)
35 #else
36 #define                             UX_DEMO_MAX_MESSAGE_LENGTH (UX_SLAVE_REQUEST_DATA_MAX_LENGTH)
37 #endif
38 #define                             UX_DEMO_N_CLOCKS           (1)
39 #define                             UX_DEMO_N_DATA_RATES       (1)
40 #define                             UX_DEMO_BULK_OUT_EP         0x02
41 #define                             UX_DEMO_BULK_IN_EP          0x81
42 #define                             UX_DEMO_INTERRUPT_IN_EP     0x83
43 #define                             UX_DEMO_INTERRUPT_IN_SIZE   (8)
44 
45 /* Define local/extern function prototypes.  */
46 static VOID                                test_thread_entry(ULONG);
47 static TX_THREAD                           tx_test_thread_host_simulation;
48 static TX_THREAD                           tx_test_thread_slave_simulation;
49 static VOID                                tx_test_thread_host_simulation_entry(ULONG);
50 static VOID                                tx_test_thread_slave_simulation_entry(ULONG);
51 
52 static VOID                                ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
53 static VOID                                ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
54 static VOID                                ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
55 
56 static UINT                                ux_test_ccid_icc_power_on(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
57 static UINT                                ux_test_ccid_icc_power_off(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
58 static UINT                                ux_test_ccid_get_slot_status(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
59 static UINT                                ux_test_ccid_xfr_block(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
60 static UINT                                ux_test_ccid_get_parameters(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
61 static UINT                                ux_test_ccid_reset_parameters(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
62 static UINT                                ux_test_ccid_set_parameters(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
63 static UINT                                ux_test_ccid_escape(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
64 static UINT                                ux_test_ccid_icc_clock(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
65 static UINT                                ux_test_ccid_t0_apdu(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
66 static UINT                                ux_test_ccid_secure(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
67 static UINT                                ux_test_ccid_mechanical(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
68 static UINT                                ux_test_ccid_abort(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
69 static UINT                                ux_test_ccid_set_data_rate_and_clock_frequency(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg);
70 
71 /* Define global data structures.  */
72 static UCHAR                        usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
73 
74 static UX_DEVICE                    *host_device = UX_NULL;
75 static UCHAR                        host_bulk_out[UX_DEMO_MAX_MESSAGE_LENGTH];
76 static UCHAR                        host_bulk_out_busy[UX_DEMO_MAX_MESSAGE_LENGTH];
77 static UCHAR                        host_bulk_in[UX_DEMO_MAX_MESSAGE_LENGTH];
78 static ULONG                        host_bulk_in_length;
79 static UCHAR                        host_interrupt_in[UX_DEMO_INTERRUPT_IN_SIZE];
80 static ULONG                        host_interrupt_in_length;
81 
82 static UX_HOST_CLASS_DUMMY          *host_ccid = UX_NULL;
83 
84 static struct _SLOT_TESTER {
85     TX_SEMAPHORE semaphore;
86     UINT         state;
87     ULONG        timeout;
88     ULONG        flags;
89 } slot_tester[UX_DEMO_MAX_SLOT_INDEX + 1];
90 #define SLOT_TESTER_FLAG_ABORT      (1u)
91 #define SLOT_TESTER_STATE_IDLE      (0u)
92 #define SLOT_TESTER_STATE_START     (1u)
93 #define SLOT_TESTER_STATE_WAIT      (2u)
94 #define SLOT_TESTER_STATE_NEXT      (3u)
95 
96 static ULONG                        enum_counter;
97 
98 static ULONG                        error_counter;
99 static ULONG                        error_callback_counter;
100 
101 static ULONG                        set_cfg_counter;
102 
103 static ULONG                        rsc_mem_alloc_cnt_on_set_cfg;
104 static ULONG                        rsc_mem_free_on_set_cfg;
105 static ULONG                        rsc_sem_on_set_cfg;
106 static ULONG                        rsc_sem_get_on_set_cfg;
107 static ULONG                        rsc_mutex_on_set_cfg;
108 
109 static ULONG                        rsc_enum_sem_usage;
110 static ULONG                        rsc_enum_sem_get_count;
111 static ULONG                        rsc_enum_mutex_usage;
112 static ULONG                        rsc_enum_mem_usage;
113 static ULONG                        rsc_enum_mem_alloc_count;
114 
115 static ULONG                        rsc_test_sem_usage;
116 static ULONG                        rsc_test_sem_get_count;
117 static ULONG                        rsc_test_mutex_usage;
118 static ULONG                        rsc_test_mem_alloc_count;
119 
120 static UX_DEVICE_CLASS_CCID_HANDLES device_ccid_handles =
121 {
122     ux_test_ccid_icc_power_on,
123     ux_test_ccid_icc_power_off,
124     ux_test_ccid_get_slot_status,
125     ux_test_ccid_xfr_block,
126     ux_test_ccid_get_parameters,
127     ux_test_ccid_reset_parameters,
128     ux_test_ccid_set_parameters,
129     ux_test_ccid_escape,
130     ux_test_ccid_icc_clock,
131     ux_test_ccid_t0_apdu,
132     ux_test_ccid_secure,
133     ux_test_ccid_mechanical,
134     ux_test_ccid_abort,
135     ux_test_ccid_set_data_rate_and_clock_frequency,
136 };
137 static ULONG                                device_ccid_clocks[] =
138 {
139     14320,
140 };
141 static ULONG                                device_ccid_data_rates[] =
142 {
143     115200,
144 };
145 static UX_DEVICE_CLASS_CCID                 *device_ccid = UX_NULL;
146 static UX_DEVICE_CLASS_CCID_PARAMETER       device_ccid_parameter;
147 static UCHAR                                device_ccid_soft_reset_count = 0;
148 
149 static struct _TEST_CCID_CALLBACK_LOG {
150     UX_DEVICE_CLASS_CCID_HANDLE             handle;
151     ULONG                                   buf_length;
152     UCHAR                                   buf[UX_DEMO_MAX_MESSAGE_LENGTH + 4];
153 }                                           device_ccid_callback_log;
ux_test_callback_log(UX_DEVICE_CLASS_CCID_HANDLE handle,UCHAR * ccid_msg)154 static inline void ux_test_callback_log(UX_DEVICE_CLASS_CCID_HANDLE handle, UCHAR *ccid_msg)
155 {
156 ULONG buf_length;
157     device_ccid_callback_log.handle = handle;
158     if (ccid_msg == UX_NULL)
159     {
160         device_ccid_callback_log.buf[0] = 0;
161         device_ccid_callback_log.buf_length = 0;
162         return;
163     }
164     buf_length = UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_GET(ccid_msg) + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
165     UX_TEST_ASSERT(buf_length <= UX_DEMO_MAX_MESSAGE_LENGTH);
166     _ux_utility_memory_copy(device_ccid_callback_log.buf, ccid_msg, buf_length);
167     device_ccid_callback_log.buf_length = buf_length;
168 }
169 
170 /* Define device framework.  */
171 
172 #define _W(w)   UX_W0(w),UX_W1(w)
173 #define _DW(dw) UX_DW0(dw),UX_DW1(dw),UX_DW2(dw),UX_DW3(dw)
174 
175 #define _CONFIGURATION_DESCRIPTOR(total_len, n_ifc, cfg_val)                    \
176     0x09, 0x02, UX_W0(total_len), UX_W1(total_len), (n_ifc), (cfg_val),         \
177     0x00, 0xc0, 0x32,
178 
179 #define _INTERFACE_DESCRIPTOR(ifc_n, alt, n_ep, cls, sub, protocol)             \
180     0x09, 0x04, (ifc_n), (alt), (n_ep), (cls), (sub), (protocol), 0x00,
181 
182 #define _SMART_CARD_DESCRIPTORS                                                 \
183     0x36, /* bLength.  */                                                       \
184     0x21, /* bDescriptorType.  */                                               \
185     0x10, 0x01, /* bcdCCID.  */                                                 \
186     UX_DEMO_MAX_SLOT_INDEX, /* bMaxSlotIndex.  */                               \
187     0x01, /* bVoltageSupport (1-5V,2-3.0V,4-1.8V). */                           \
188     0x00, 0x00, 0x00, 0x00, /* dwProtocols PPPP, RRRR.  */                      \
189     _DW(14320), /* dwDefaultClock (KHz).  */                                    \
190     _DW(14320), /* dwMaximumClock (KHz).  */                                    \
191     UX_DEMO_N_CLOCKS, /* bNumClockSupported.  */                                \
192     _DW(115200), /* dwDataRate (bps).  */                                       \
193     _DW(115200), /* dwMaxDataRate (bps).  */                                    \
194     UX_DEMO_N_DATA_RATES, /* bNumDataRatesSupported.  */                        \
195     0x00, 0x00, 0x00, 0x00, /* dwMaxIFSD.  */                                   \
196     0x00, 0x00, 0x00, 0x00, /* dwSynchProtocols PPPP, RRRR.  */                 \
197     0x00, 0x00, 0x00, 0x00, /* dwMechanical (1-accept,2-eject,4-capture,8-lock/unlock).  */\
198     0x00, 0x00, 0x00, 0x00, /* dwFeatures.  */                                  \
199     _DW(1024), /* dwMaxCCIDMessageLength.  */                                   \
200     0, /* bClassGetResponse.  */                                                \
201     0, /* bClassEnvelope.  */                                                   \
202     _W(0x0000), /* wLcdLayout, XXYY.  */                                        \
203     0x3, /* bPINSupport, 1-Verification, 2-Modification.  */                    \
204     UX_DEMO_MAX_BUSY_SLOTS, /* bMaxCCIDBusySlots.  */
205 
206 
207 #define _ENDPOINT_DESCRIPTOR(addr, attr, pktsize, interval)                     \
208     0x07, 0x05, (addr), (attr), UX_W0(pktsize), UX_W1(pktsize), (interval),
209 
210 #define _CFG_TOTAL_LEN (9+9+0x36+7+7+7)
211 
212 #define             STRING_FRAMEWORK_LENGTH                 47
213 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            2
214 
215 static unsigned char device_framework_full_speed[] = {
216 
217     /* Device descriptor     18 bytes
218        0xEF bDeviceClass:    Composite class code
219        0x02 bDeviceSubclass: class sub code
220        0x00 bDeviceProtocol: Device protocol
221        idVendor & idProduct - http://www.linux-usb.org/usb.ids
222     */
223     0x12, 0x01, 0x10, 0x01,
224     0x00, 0x00, 0x00,
225     0x08,
226     0x84, 0x84, 0x00, 0x00,
227     0x00, 0x01,
228     0x01, 0x02, 0x03,
229     0x01,
230 
231     _CONFIGURATION_DESCRIPTOR(_CFG_TOTAL_LEN, 1, 1)
232     _INTERFACE_DESCRIPTOR(0, 0, 3, 0x0B, 0x00, 0x00)
233     _SMART_CARD_DESCRIPTORS
234     _ENDPOINT_DESCRIPTOR(UX_DEMO_BULK_OUT_EP,       0x02, 64, 0x00)
235     _ENDPOINT_DESCRIPTOR(UX_DEMO_BULK_IN_EP,        0x02, 64, 0x00)
236     _ENDPOINT_DESCRIPTOR(UX_DEMO_INTERRUPT_IN_EP,   0x03, UX_DEMO_INTERRUPT_IN_SIZE, 0x04)
237 };
238 
239 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      sizeof(device_framework_full_speed)
240 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      sizeof(device_framework_full_speed)
241 #define             device_framework_high_speed             device_framework_full_speed
242 
243 static unsigned char string_framework[] = {
244 
245     /* Manufacturer string descriptor : Index 1 - "AzureRTOS" */
246     0x09, 0x04, 0x01, 9,
247         'A','z','u','r','e','R','T','O','S',
248 
249     /* Product string descriptor : Index 2 - "ccid device" */
250     0x09, 0x04, 0x02, 11,
251         'C','C','I','D',' ','d','e','v','i','c','e',
252 
253     /* Serial Number string descriptor : Index 3 - "0001" */
254     0x09, 0x04, 0x03, 0x04,
255         0x30, 0x30, 0x30, 0x31
256 };
257 
258 
259     /* Multiple languages are supported on the device, to add
260        a language besides english, the unicode language code must
261        be appended to the language_id_framework array and the length
262        adjusted accordingly. */
263 static unsigned char language_id_framework[] = {
264 
265     /* English. */
266         0x09, 0x04
267 };
268 
269 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
270 
271 /* Test interactions */
272 
273 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
274 /* function, request to match,
275    port action, port status,
276    request action, request EP, request data, request actual length, request status,
277    status, additional callback,
278    no_return */
279 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
280         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
281         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
282         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
283         UX_TRUE}, /* Invoke callback & continue */
284 {   0   }
285 };
286 
287 /* Define the ISR dispatch.  */
288 
289 extern VOID    (*test_isr_dispatch)(void);
290 
291 
292 /* Prototype for test control return.  */
293 
294 void  test_control_return(UINT status);
295 
296 
297 /* Define the ISR dispatch routine.  */
298 
test_isr(void)299 static void    test_isr(void)
300 {
301 
302     /* For further expansion of interrupt-level testing.  */
303 }
304 
test_slave_change_function(ULONG change)305 static UINT test_slave_change_function(ULONG change)
306 {
307     return 0;
308 }
309 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)310 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
311 {
312     // printf("hCbChange: %lx %p %p\n", event, (VOID*)cls, inst);
313     switch(event)
314     {
315 
316     case UX_DEVICE_INSERTION:
317         host_ccid = inst;
318         break;
319 
320     case UX_DEVICE_REMOVAL:
321         if (host_ccid == inst)
322             host_ccid = UX_NULL;
323         break;
324 
325     case UX_DEVICE_CONNECTION:
326         host_device = (UX_DEVICE *)inst;
327         break;
328 
329     case UX_DEVICE_DISCONNECTION:
330         if ((VOID *)host_device == inst)
331             host_device = UX_NULL;
332         break;
333 
334 #if defined(UX_HOST_STANDALONE)
335     case UX_STANDALONE_WAIT_BACKGROUND_TASK:
336         tx_thread_relinquish();
337         break;
338 #endif
339 
340     default:
341         break;
342     }
343     return 0;
344 }
345 
test_ccid_instance_activate(VOID * dummy_instance)346 static VOID    test_ccid_instance_activate(VOID *dummy_instance)
347 {
348     if (device_ccid == UX_NULL)
349         device_ccid = (UX_DEVICE_CLASS_CCID *)dummy_instance;
350 }
test_ccid_instance_deactivate(VOID * dummy_instance)351 static VOID    test_ccid_instance_deactivate(VOID *dummy_instance)
352 {
353     if ((VOID*)device_ccid == dummy_instance)
354         device_ccid = UX_NULL;
355 }
test_ccid_soft_reset(VOID * dummy_instance)356 static VOID    test_ccid_soft_reset(VOID *dummy_instance)
357 {
358     device_ccid_soft_reset_count ++;
359 }
360 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)361 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
362 {
363     error_callback_counter ++;
364 }
365 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)366 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
367 {
368 
369     set_cfg_counter ++;
370 
371     rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
372 
373     rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
374 
375     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
376     rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
377     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
378 }
379 
380 /* Define what the initial system looks like.  */
381 
382 #ifdef CTEST
test_application_define(void * first_unused_memory)383 void test_application_define(void *first_unused_memory)
384 #else
385 void    usbx_host_class_ccid_busy_abort_test_application_define(void *first_unused_memory)
386 #endif
387 {
388 
389 UINT                    status;
390 CHAR *                  stack_pointer;
391 CHAR *                  memory_pointer;
392 
393 
394     printf("Running CCID Busy and Abort Test.................................... ");
395 #if !UX_TEST_MULTI_EP_OVER(2)
396     printf("Skip\n");
397     test_control_return(0);
398     return;
399 #endif
400 
401     /* Reset testing counts. */
402     ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
403     ux_test_utility_sim_mem_alloc_count_reset();
404     ux_test_utility_sim_mutex_create_count_reset();
405     ux_test_utility_sim_sem_create_count_reset();
406     ux_test_utility_sim_sem_get_count_reset();
407     /* Reset error generations */
408     ux_test_utility_sim_sem_error_generation_stop();
409     ux_test_utility_sim_mutex_error_generation_stop();
410     ux_test_utility_sim_sem_get_error_generation_stop();
411 
412     /* Initialize the free memory pointer */
413     stack_pointer = (CHAR *) usbx_memory;
414     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 4);
415 
416     /* Initialize USBX Memory */
417     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
418 
419     /* Check for error.  */
420     if (status != UX_SUCCESS)
421     {
422 
423         printf(" ERROR #%d\n", __LINE__);
424         test_control_return(1);
425     }
426 
427     /* Register the error callback. */
428     _ux_utility_error_callback_register(test_ux_error_callback);
429 
430     /* The code below is required for installing the host portion of USBX */
431     status =  ux_host_stack_initialize(test_host_change_function);
432     if (status != UX_SUCCESS)
433     {
434 
435         printf(" ERROR #%d\n", __LINE__);
436         test_control_return(1);
437     }
438 
439     /* Register Host DUMMY class.  */
440     status =  ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_entry);
441     if (status != UX_SUCCESS)
442     {
443 
444         printf(" ERROR #3\n");
445         test_control_return(1);
446     }
447 
448     /* The code below is required for installing the device portion of USBX. No call back for
449        device status change in this example. */
450     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
451                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
452                                        string_framework, STRING_FRAMEWORK_LENGTH,
453                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
454                                        test_slave_change_function);
455     if(status!=UX_SUCCESS)
456     {
457 
458         printf(" ERROR #%d\n", __LINE__);
459         test_control_return(1);
460     }
461 
462     /* Set the parameters for callback when insertion/extraction of a ccid device.  */
463     _ux_utility_memory_set(&device_ccid_parameter, 0, sizeof(device_ccid_parameter));
464     device_ccid_parameter.ux_device_class_ccid_handles             = &device_ccid_handles;
465     device_ccid_parameter.ux_device_class_ccid_instance_activate   = test_ccid_instance_activate;
466     device_ccid_parameter.ux_device_class_ccid_instance_deactivate = test_ccid_instance_deactivate;
467     device_ccid_parameter.ux_device_class_ccid_max_n_slots         = UX_DEMO_MAX_SLOT_INDEX + 1;
468     device_ccid_parameter.ux_device_class_ccid_max_n_busy_slots    = UX_DEMO_MAX_BUSY_SLOTS;
469     device_ccid_parameter.ux_device_class_ccid_max_transfer_length = UX_DEMO_MAX_MESSAGE_LENGTH;
470     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
471     status  = ux_device_stack_class_register(_ux_system_device_class_ccid_name,
472                                              ux_device_class_ccid_entry,
473                                              1, 0, &device_ccid_parameter);
474     /* Initialize the simulated device controller.  */
475     status =  _ux_test_dcd_sim_slave_initialize();
476 
477     /* Check for error.  */
478     if (status != TX_SUCCESS)
479     {
480 
481         printf(" ERROR #%d\n", __LINE__);
482         test_control_return(1);
483     }
484 
485     /* Register all the USB host controllers available in this system */
486     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
487     if (status != UX_SUCCESS)
488     {
489 
490         printf(" ERROR #%d\n", __LINE__);
491         test_control_return(1);
492     }
493 
494     /* Create the main host simulation thread.  */
495     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
496             stack_pointer, UX_DEMO_STACK_SIZE,
497             20, 20, 1, TX_AUTO_START);
498 
499     /* Check for error.  */
500     if (status != TX_SUCCESS)
501     {
502 
503         printf(" ERROR #9\n");
504         test_control_return(1);
505     }
506 
507     /* Create the main slave simulation  thread.  */
508     stack_pointer += UX_DEMO_STACK_SIZE;
509     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
510             stack_pointer, UX_DEMO_STACK_SIZE,
511             20, 20, 1, TX_AUTO_START);
512 
513     /* Check for error.  */
514     if (status != TX_SUCCESS)
515     {
516 
517         printf(" ERROR #10\n");
518         test_control_return(1);
519     }
520 
521     for (int i = 0; i <= UX_DEMO_MAX_SLOT_INDEX; i ++)
522     {
523         slot_tester[i].timeout = TX_WAIT_FOREVER;
524         status = tx_semaphore_create(&slot_tester[i].semaphore, "slot_test_semaphore", 0);
525         UX_TEST_ASSERT(status == TX_SUCCESS);
526     }
527 }
528 
_test_check_host_connection_error(VOID)529 static UINT _test_check_host_connection_error(VOID)
530 {
531     if (device_ccid && host_ccid)
532         return(UX_SUCCESS);
533     if (error_callback_counter >= 3)
534         return(UX_SUCCESS);
535     return(UX_ERROR);
536 }
537 
_test_check_host_connection_success(VOID)538 static UINT _test_check_host_connection_success(VOID)
539 {
540     if (device_ccid && host_ccid)
541         return(UX_SUCCESS);
542     return(UX_ERROR);
543 }
544 
_test_check_host_disconnection_success(VOID)545 static UINT _test_check_host_disconnection_success(VOID)
546 {
547     if (device_ccid == UX_NULL && host_ccid == UX_NULL)
548         return(UX_SUCCESS);
549     return(UX_ERROR);
550 }
551 
_ccid_message_bulk_out_in(UCHAR * out,ULONG out_length,UCHAR * in,ULONG * in_length)552 static UINT _ccid_message_bulk_out_in(UCHAR *out, ULONG out_length, UCHAR *in, ULONG *in_length)
553 {
554 ULONG           payload_size;
555 ULONG           total_length, actual_length;
556 UINT            status = UX_FUNCTION_NOT_SUPPORTED;
557     if (out)
558     {
559         total_length = out_length;
560         status = _ux_host_class_dummy_transfer(host_ccid, UX_DEMO_BULK_OUT_EP, 0, out, total_length, &actual_length);
561         if (status != UX_SUCCESS)
562         {
563             printf("BulkOUT fail: 0x%x\n", status);
564             return(status);
565         }
566     }
567     if (in)
568     {
569         payload_size = _ux_host_class_dummy_get_max_payload_size(host_ccid, UX_DEMO_BULK_IN_EP, 0);
570         while(1)
571         {
572             status = _ux_host_class_dummy_transfer(host_ccid, UX_DEMO_BULK_IN_EP, 0, in, payload_size, &actual_length);
573             *in_length = actual_length;
574             if (status != UX_SUCCESS)
575             {
576                 printf("BulkIN fail: 0x%x\n", status);
577                 return(status);
578             }
579             /* Check time extension.  */
580             if (((in[7] >> 6) & 0x3u) == 0x2)
581             {
582                 /* Try to read another packet.  */
583                 // printf("TimeExtension\n");
584                 continue;
585             }
586             /* Check short packet.  */
587             if (actual_length < payload_size)
588                 return(status);
589             else
590                 break;
591         }
592         /* Read remaining message.  */
593         total_length = UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_GET(in);
594         total_length += UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
595         //printf("FirstPacket, total %ld\n", total_length);
596         in += payload_size;
597         total_length -= payload_size;
598         if (total_length)
599         {
600             status = _ux_host_class_dummy_transfer(host_ccid, UX_DEMO_BULK_IN_EP, 0, in, total_length, &actual_length);
601             *in_length += actual_length;
602         }
603     }
604     else
605     {
606         /* Let other threads run.  */
607         tx_thread_sleep(1);
608     }
609     return(status);
610 }
611 
_ccid_message_interrupt_in(UCHAR * in,ULONG * in_length)612 static UINT _ccid_message_interrupt_in(UCHAR *in, ULONG *in_length)
613 {
614 ULONG           payload_size = _ux_host_class_dummy_get_max_payload_size(host_ccid, UX_DEMO_INTERRUPT_IN_EP, 0);
615 UINT            status;
616     status = _ux_host_class_dummy_transfer(host_ccid, UX_DEMO_INTERRUPT_IN_EP, 0, in, payload_size, in_length);
617     return(status);
618 }
619 
_ccid_abort(UCHAR bSlot,UCHAR bSeq)620 static UINT _ccid_abort(UCHAR bSlot, UCHAR bSeq)
621 {
622 UX_ENDPOINT     *endpoint = _ux_host_class_dummy_get_endpoint(host_ccid, 0, 0);
623 UX_TRANSFER     *transfer = &endpoint->ux_endpoint_transfer_request;
624 UX_INTERFACE    *interface = host_ccid->ux_host_class_dummy_interface;
625 UINT            status;
626 ULONG           length;
627 UCHAR           cmd[10], rsp[10];
628     /* Issue Abort request.  */
629     transfer->ux_transfer_request_type              = 0x21;
630     transfer->ux_transfer_request_function          = 0x01;
631     transfer->ux_transfer_request_index             = interface->ux_interface_descriptor.bInterfaceNumber;
632     transfer->ux_transfer_request_value             = bSlot | (bSeq << 8);
633     transfer->ux_transfer_request_requested_length  = 0;
634     status = ux_host_stack_transfer_request(transfer);
635     if (status != UX_SUCCESS)
636     {
637         return(status);
638     }
639     /* Issue Abort Message.  */
640     _ux_utility_memory_set(cmd, 0, 10);
641     cmd[0] = 0x72;
642     cmd[5] = bSlot;
643     cmd[6] = bSeq;
644     status = _ccid_message_bulk_out_in(cmd, 10, rsp, &length);
645     return(status);
646 }
647 
648 #define _TEST_CCID_BULK_OUT_CHECK(h, l, b) \
649     UX_TEST_ASSERT(status == UX_SUCCESS); \
650     UX_TEST_ASSERT(device_ccid_callback_log.handle == (h)); \
651     if ((h) != UX_NULL) { \
652         UX_TEST_ASSERT(device_ccid_callback_log.buf_length == (l)); \
653         if (b) { \
654             UX_TEST_ASSERT(_ux_utility_memory_compare(device_ccid_callback_log.buf, (b), (l)) == UX_SUCCESS); \
655         } \
656     }
657 
658 #define _TEST_CCID_BULK_IN_HEADER_CHECK(type,len,slot,seq,stat,err) \
659     UX_TEST_ASSERT(host_bulk_in[0] == (type));\
660     UX_TEST_ASSERT((len) == _ux_utility_long_get(host_bulk_in + 1));\
661     UX_TEST_ASSERT(host_bulk_in[5] == (slot));\
662     UX_TEST_ASSERT(host_bulk_in[6] == (seq));\
663     UX_TEST_ASSERT(host_bulk_in[7] == (stat)); /* bStatus: not present.  */\
664     UX_TEST_ASSERT(host_bulk_in[8] == (err));
665 
_buffer_dump(VOID * buf,ULONG len)666 static VOID _buffer_dump(VOID *buf, ULONG len)
667 {
668 ULONG       i;
669     for(i = 0; i < len; i ++)
670         printf(" %02x", ((UCHAR *)buf)[i]);
671     printf("\n");
672 }
673 
_ccid_icc_insert_test(VOID)674 static VOID _ccid_icc_insert_test(VOID)
675 {
676 UINT        status;
677 
678     stepinfo(">>>>>>>>>> Test Insert\n");
679     ux_device_class_ccid_icc_insert(device_ccid, 0, 0);
680     ux_device_class_ccid_icc_insert(device_ccid, 1, 0);
681     status = _ccid_message_interrupt_in(host_interrupt_in, &host_interrupt_in_length);
682     UX_TEST_ASSERT(status == UX_SUCCESS);
683     UX_TEST_ASSERT(host_interrupt_in_length == 2);
684     UX_TEST_ASSERT(host_interrupt_in[0] == 0x50);
685 
686 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 1
687     if (host_interrupt_in[1] == 0x03)
688     {
689         status = _ccid_message_interrupt_in(host_interrupt_in, &host_interrupt_in_length);
690         UX_TEST_ASSERT(host_interrupt_in_length == 2);
691         UX_TEST_ASSERT(host_interrupt_in[0] == 0x50);
692         UX_TEST_ASSERT(host_interrupt_in[1] == 0x0D); /* Slot0: exist, Slot1: insert.  */
693     }
694     else
695         UX_TEST_ASSERT(host_interrupt_in[1] == 0x0F);
696 #else
697     UX_TEST_ASSERT(host_interrupt_in[1] == 0x03); /* Slot0: exist.  */
698 #endif
699 
700 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 1
701     #define _RM_SLOT   1
702     #define _RM_CHECK  0x09 /* Slot0: exist, Slot1: remove.  */
703 #else
704     #define _RM_SLOT   0
705     #define _RM_CHECK  0x02 /* Slot0: remove, Slot1: remove.  */
706 #endif
707     stepinfo(">>>>>>>>>> Test Remove\n");
708     ux_device_class_ccid_icc_remove(device_ccid, _RM_SLOT);
709     status = _ccid_message_interrupt_in(host_interrupt_in, &host_interrupt_in_length);
710     UX_TEST_ASSERT(status == UX_SUCCESS);
711     UX_TEST_ASSERT(host_interrupt_in_length == 2);
712     UX_TEST_ASSERT(host_interrupt_in[0] == 0x50);
713     UX_TEST_ASSERT(host_interrupt_in[1] == _RM_CHECK);
714 
715 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 1
716     #define _INS_SLOT   1
717     #define _INS_CHECK  0x0D /* Slot0: exist, Slot1: insert.  */
718 #else
719     #define _INS_SLOT   0
720     #define _INS_CHECK  0x03 /* Slot0: insert, Slot1: remove.  */
721 #endif
722     stepinfo(">>>>>>>>>> Test Insert (auto)\n");
723     ux_device_class_ccid_icc_insert(device_ccid, _INS_SLOT, 1);
724     status = _ccid_message_interrupt_in(host_interrupt_in, &host_interrupt_in_length);
725     UX_TEST_ASSERT(status == UX_SUCCESS);
726     UX_TEST_ASSERT(host_interrupt_in_length == 2);
727     UX_TEST_ASSERT(host_interrupt_in[0] == 0x50);
728     UX_TEST_ASSERT(host_interrupt_in[1] == _INS_CHECK); /* Slot0: exist, Slot1: insert.  */
729 }
730 
_ccid_icc_power_on_off_test(VOID)731 static VOID _ccid_icc_power_on_off_test(VOID)
732 {
733 UINT        status;
734     /* PC_to_RDR_IccPowerOn, RDR_to_PC_DataBlock   */
735 
736     /* Message(IccPowerOn).  */
737     stepinfo(">>>>>>>>>> Test IccPowerOn\n");
738     _ux_utility_memory_set(host_bulk_out, 0, 10);
739     host_bulk_out[0] = 0x62;
740     host_bulk_out[5] = 0; /* bSlot.  */
741     host_bulk_out[6] = 0; /* bSeq.   */
742     _ux_utility_long_put(host_bulk_out+1, 0);
743     host_bulk_out[7] = 2;
744     device_ccid_callback_log.handle = UX_NULL;
745     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
746     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_on, 10, host_bulk_out)
747     _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 0, 0, 0, 0)
748 
749 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 1
750 
751     /* Message(IccPowerOff).  */
752     stepinfo(">>>>>>>>>> Test IccPowerOff\n");
753     host_bulk_out[0] = 0x63;
754     host_bulk_out[5] = 0; /* bSlot.  */
755     host_bulk_out[6] = 1; /* bSeq.   */
756     host_bulk_out[7] = 0;
757     device_ccid_callback_log.handle = UX_NULL;
758     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
759     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_off, 10, host_bulk_out)
760     _TEST_CCID_BULK_IN_HEADER_CHECK(0x81, 0, 0, 1, 1, 0)
761 
762     /* Message(IccPowerOff) -> BUSY_WITH_AUTO_SEQUENCE.  */
763     stepinfo(">>>>>>>>>> Test IccPowerOff -> BUSY_WITH_AUTO_SEQUENCE\n");
764     host_bulk_out[0] = 0x63;
765     host_bulk_out[5] = 1; /* bSlot.  */
766     host_bulk_out[6] = 0; /* bSeq.   */
767     device_ccid_callback_log.handle = UX_NULL;
768     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
769     _TEST_CCID_BULK_OUT_CHECK(UX_NULL, 10, host_bulk_out)
770     _TEST_CCID_BULK_IN_HEADER_CHECK(0x81, 0, 1, 0, 0x41, 0xF2)
771 
772     /* Message(IccPowerOff).  */
773     stepinfo(">>>>>>>>>> Test seq done - IccPowerOff\n");
774     ux_device_class_ccid_auto_seq_done(device_ccid, 1, UX_DEVICE_CLASS_CCID_ICC_ACTIVE);
775     device_ccid_callback_log.handle = UX_NULL;
776     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
777     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_off, 10, host_bulk_out)
778     _TEST_CCID_BULK_IN_HEADER_CHECK(0x81, 0, 1, 0, 1, 0)
779 #else
780 
781     /* Message(IccPowerOff) -> BUSY_WITH_AUTO_SEQUENCE.  */
782     stepinfo(">>>>>>>>>> Test IccPowerOff -> BUSY_WITH_AUTO_SEQUENCE\n");
783     host_bulk_out[0] = 0x63;
784     host_bulk_out[5] = 0; /* bSlot.  */
785     host_bulk_out[6] = 1; /* bSeq.   */
786     device_ccid_callback_log.handle = UX_NULL;
787     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
788     _TEST_CCID_BULK_OUT_CHECK(UX_NULL, 10, host_bulk_out)
789     _TEST_CCID_BULK_IN_HEADER_CHECK(0x81, 0, 0, 1, 0x41, 0xF2)
790 
791     /* Message(IccPowerOff).  */
792     stepinfo(">>>>>>>>>> Test seq done - IccPowerOff\n");
793     ux_device_class_ccid_auto_seq_done(device_ccid, 0, UX_DEVICE_CLASS_CCID_ICC_ACTIVE);
794     device_ccid_callback_log.handle = UX_NULL;
795     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
796     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_off, 10, host_bulk_out)
797     _TEST_CCID_BULK_IN_HEADER_CHECK(0x81, 0, 0, 1, 1, 0)
798 #endif
799 
800     /* Message(IccPowerOn).  */
801     host_bulk_out[0] = 0x62;
802     host_bulk_out[5] = 0; /* bSlot.  */
803     host_bulk_out[6] = 3; /* bSeq.   */
804     host_bulk_out[7] = 1;
805     device_ccid_callback_log.handle = UX_NULL;
806     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
807     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_on, 10, host_bulk_out)
808     _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 0, 3, 0, 0)
809 }
810 
_ccid_invalid_slot_test(VOID)811 static VOID _ccid_invalid_slot_test(VOID)
812 {
813 UINT        status;
814     /* PC_to_RDR_IccPowerOn, RDR_to_PC_DataBlock   */
815 
816     /* Message(IccPowerOn).  */
817     _ux_utility_memory_set(host_bulk_out, 0, 10);
818     host_bulk_out[0] = 0x62;
819     host_bulk_out[5] = 0; /* bSlot.  */
820     host_bulk_out[6] = 0; /* bSeq.   */
821     _ux_utility_long_put(host_bulk_out+1, 0);
822     host_bulk_out[7] = 1;
823     device_ccid_callback_log.handle = UX_NULL;
824     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
825     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_on, 10, host_bulk_out)
826     _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 0, 0, 0, 0)
827 
828 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 1
829 
830     /* Good slot.  */
831     host_bulk_out[5] = 1; /* bSlot.  */
832     device_ccid_callback_log.handle = UX_NULL;
833     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
834     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_on, 10, host_bulk_out)
835     _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 1, 0, 0, 0)
836 #endif
837 
838 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 2
839 
840     /* Good slot.  */
841     host_bulk_out[5] = 2; /* bSlot.  */
842     device_ccid_callback_log.handle = UX_NULL;
843     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
844     _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_icc_power_on, 10, host_bulk_out)
845     _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 2, 0, 0, 0)
846 #endif
847 
848 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 3
849 
850     /* Invalid slot.  */
851     host_bulk_out[5] = 3; /* bSlot.  */
852     device_ccid_callback_log.handle = UX_NULL;
853     status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
854     _TEST_CCID_BULK_OUT_CHECK(UX_NULL, 10, host_bulk_out)
855     _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 3, 0, 0x42, 5)
856 #endif
857 }
858 
_ccid_busy_slot_test(VOID)859 static VOID _ccid_busy_slot_test(VOID)
860 {
861 UINT        status;
862     stepinfo(">>>>>>>>>> Test CCID Busy ...\n");
863 
864     /* PC_to_RDR_XfrBlock, RDR_to_PC_DataBlock.  */
865     _ux_utility_memory_set(host_bulk_out, 0, 10);
866     _ux_utility_memory_set(host_bulk_out_busy, 0, 10);
867     /* Same slot response busy.  */
868     {
869         stepinfo(">>>>>>>>>> Test CCID Busy - Xfer blocked\n");
870         /* _XfrBlock ... blocked.  */
871         host_bulk_out[0] = 0x6F;
872         host_bulk_out[5] = 0; /* bSlot.  */
873         host_bulk_out[6] = 8; /* bSeq.   */
874         _ux_utility_long_put(host_bulk_out+1, 0);
875         device_ccid_callback_log.handle = UX_NULL;
876         status = _ccid_message_bulk_out_in(host_bulk_out, 10, UX_NULL, &host_bulk_in_length);
877         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out)
878 
879         stepinfo(">>>>>>>>>> Test CCID Busy - Xfer response busy\n");
880         /* _XfrBlock ... response busy.  */
881         host_bulk_out_busy[0] = 0x6F;
882         host_bulk_out_busy[5] = 0; /* bSlot.  */
883         host_bulk_out_busy[6] = 8; /* bSeq.   */
884         _ux_utility_long_put(host_bulk_out_busy+1, 0);
885         host_bulk_out_busy[6] = 9; /* bSeq.   */
886         device_ccid_callback_log.handle = UX_NULL;
887         status = _ccid_message_bulk_out_in(host_bulk_out_busy, 10, host_bulk_in, &host_bulk_in_length);
888 #if defined(UX_DEVICE_STANDALONE)
889         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out) /* Task is polled */
890 #else
891         _TEST_CCID_BULK_OUT_CHECK(UX_NULL, 10, host_bulk_out)
892 #endif
893         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 0, 9, 0x40, 0xE0)
894 
895         stepinfo(">>>>>>>>>> Test CCID Busy - Xfer done\n");
896         /* Response.  */
897 #if defined(UX_DEVICE_STANDALONE)
898         slot_tester[0].state = SLOT_TESTER_STATE_NEXT;
899 #else
900         tx_semaphore_put(&slot_tester[0].semaphore);
901 #endif
902         status = _ccid_message_bulk_out_in(UX_NULL, 10, host_bulk_in, & host_bulk_in_length);
903         UX_TEST_ASSERT(status == UX_SUCCESS);
904         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 64-10, 0, 8, 0, 0)
905     }
906 #if UX_DEVICE_CLASS_CCID_MAX_N_SLOTS > 1
907     /* Max number of slots exceed, response busy.  */
908     {
909         /* _XfrBlock(0) ... blocked.  */
910         host_bulk_out[5] = 0; /* bSlot.  */
911         host_bulk_out[6] = 8; /* bSeq.   */
912         device_ccid_callback_log.handle = UX_NULL;
913         status = _ccid_message_bulk_out_in(host_bulk_out, 10, UX_NULL, &host_bulk_in_length);
914         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out)
915 
916         /* _XfrBlock(1) ... blocked.  */
917         host_bulk_out[5] = 1; /* bSlot.  */
918         host_bulk_out[6] = 2; /* bSeq.   */
919         device_ccid_callback_log.handle = UX_NULL;
920         status = _ccid_message_bulk_out_in(host_bulk_out, 10, UX_NULL, &host_bulk_in_length);
921         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out)
922 
923         /* _XfrBlock(2) ... response busy.  */
924         host_bulk_out[5] = 2; /* bSlot.  */
925         host_bulk_out[6] = 7; /* bSeq.   */
926         device_ccid_callback_log.handle = UX_NULL;
927         status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
928         _TEST_CCID_BULK_OUT_CHECK(UX_NULL, 10, host_bulk_out)
929         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 2, 7, 0x40, 0xE0)
930 
931         /* Response(1).  */
932         tx_semaphore_put(&slot_tester[1].semaphore);
933         status = _ccid_message_bulk_out_in(UX_NULL, 10, host_bulk_in, & host_bulk_in_length);
934         UX_TEST_ASSERT(status == UX_SUCCESS);
935         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 64-10, 1, 2, 0, 0)
936 
937         /* _XfrBlock(2) ... Blocked.  */
938         host_bulk_out[5] = 2; /* bSlot.  */
939         host_bulk_out[6] = 7; /* bSeq.   */
940         device_ccid_callback_log.handle = UX_NULL;
941         status = _ccid_message_bulk_out_in(host_bulk_out, 10, UX_NULL, &host_bulk_in_length);
942         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out)
943 
944         /* Response(0).  */
945         tx_semaphore_put(&slot_tester[0].semaphore);
946         status = _ccid_message_bulk_out_in(UX_NULL, 10, host_bulk_in, & host_bulk_in_length);
947         UX_TEST_ASSERT(status == UX_SUCCESS);
948         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 64-10, 0, 8, 0, 0)
949 
950         /* Response(2).  */
951         tx_semaphore_put(&slot_tester[2].semaphore);
952         status = _ccid_message_bulk_out_in(UX_NULL, 10, host_bulk_in, & host_bulk_in_length);
953         UX_TEST_ASSERT(status == UX_SUCCESS);
954         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 64-10, 2, 7, 0, 0)
955     }
956 #endif
957 
958 }
959 
_ccid_abort_test(VOID)960 static VOID _ccid_abort_test(VOID)
961 {
962 UINT        status;
963     /* PC_to_RDR_XfrBlock, RDR_to_PC_DataBlock.  */tx_thread_sleep(10);
964     _ux_utility_memory_set(host_bulk_out, 0, 10);
965     _ux_utility_memory_set(host_bulk_out_busy, 0, 10);
966     /* Same slot response busy.  */
967     {
968         /* _XfrBlock ... blocked.  */
969         stepinfo(">>>>>>>>>> Test CCID Abort - Xfer blocked\n");
970         host_bulk_out[0] = 0x6F;
971         host_bulk_out[5] = 0; /* bSlot.  */
972         host_bulk_out[6] = 8; /* bSeq.   */
973         _ux_utility_long_put(host_bulk_out+1, 0);
974         device_ccid_callback_log.handle = UX_NULL;
975         status = _ccid_message_bulk_out_in(host_bulk_out, 10, UX_NULL, &host_bulk_in_length);
976         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out)
977 
978         /* _XfrBlock ... response busy.  */
979         stepinfo(">>>>>>>>>> Test CCID Abort - Xfer busy\n");
980         host_bulk_out_busy[0] = 0x6F;
981         host_bulk_out_busy[5] = 0; /* bSlot.  */
982         host_bulk_out_busy[6] = 9; /* bSeq.   */
983         device_ccid_callback_log.handle = UX_NULL;
984         status = _ccid_message_bulk_out_in(host_bulk_out_busy, 10, host_bulk_in, &host_bulk_in_length);
985 #if defined(UX_DEVICE_STANDALONE)
986         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out) /* Still polled in wait state.  */
987 #else
988         _TEST_CCID_BULK_OUT_CHECK(UX_NULL, 10, host_bulk_out)
989 #endif
990         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 0, 0, 9, 0x40, 0xE0)
991 
992         /* Abort.  */
993         stepinfo(">>>>>>>>>> Test CCID Abort - Xfer abort\n");
994         status = _ccid_abort(0, 12);
995         UX_TEST_ASSERT(status == UX_SUCCESS);
996 
997         /* _XfrBlock ... OK.  */
998         stepinfo(">>>>>>>>>> Test CCID Abort - Xfer OK\n");
999         host_bulk_out[0] = 0x6F;
1000         host_bulk_out[5] = 0; /* bSlot.  */
1001         host_bulk_out[6] = 20; /* bSeq.   */
1002         _ux_utility_long_put(host_bulk_out+1, 0);
1003         device_ccid_callback_log.handle = UX_NULL;
1004 #if defined(UX_DEVICE_STANDALONE)
1005         slot_tester[0].state = SLOT_TESTER_STATE_NEXT;
1006 #else
1007         tx_semaphore_put(&slot_tester[0].semaphore);
1008 #endif
1009         status = _ccid_message_bulk_out_in(host_bulk_out, 10, host_bulk_in, &host_bulk_in_length);
1010         _TEST_CCID_BULK_OUT_CHECK(ux_test_ccid_xfr_block, 10, host_bulk_out)
1011         _TEST_CCID_BULK_IN_HEADER_CHECK(0x80, 64-10, 0, 20, 0, 0)
1012     }
1013 }
1014 
tx_test_thread_host_simulation_entry(ULONG arg)1015 void  tx_test_thread_host_simulation_entry(ULONG arg)
1016 {
1017 
1018 UINT                                                status;
1019 ULONG                                               test_n;
1020 ULONG                                               mem_free;
1021 ULONG                                               loop;
1022 ULONG                                               parameter_u32[64/4];
1023 USHORT                                              *parameter_u16 = (USHORT*)parameter_u32;
1024 UCHAR                                               *parameter_u8 = (UCHAR*)parameter_u32;
1025 
1026 
1027     stepinfo("\n");
1028     stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
1029     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1030     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1031     status = ux_test_sleep_break_on_success(100, _test_check_host_connection_success);
1032     UX_TEST_ASSERT(status == UX_SUCCESS);
1033 
1034     _ccid_icc_insert_test();
1035     _ccid_icc_power_on_off_test();
1036 
1037     _ccid_invalid_slot_test();
1038     _ccid_busy_slot_test();
1039     _ccid_abort_test();
1040 
1041     /* Test disconnect. */
1042     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
1043     ux_test_dcd_sim_slave_disconnect();
1044     ux_test_hcd_sim_host_disconnect();
1045     status = ux_test_sleep_break_on_success(100, _test_check_host_disconnection_success);
1046     UX_TEST_ASSERT(status == UX_SUCCESS);
1047 
1048     /* Finally disconnect the device. */
1049     ux_device_stack_disconnect();
1050 
1051     /* And deinitialize the class.  */
1052     status  = ux_device_stack_class_unregister(_ux_system_device_class_ccid_name, _ux_device_class_ccid_entry);
1053 
1054     /* Deinitialize the device side of usbx.  */
1055     _ux_device_stack_uninitialize();
1056 
1057     /* And finally the usbx system resources.  */
1058     _ux_system_uninitialize();
1059 
1060     /* Successful test.  */
1061     printf("SUCCESS!\n");
1062     test_control_return(0);
1063 
1064 }
1065 
tx_test_thread_slave_simulation_entry(ULONG arg)1066 void  tx_test_thread_slave_simulation_entry(ULONG arg)
1067 {
1068 
1069     while(1)
1070     {
1071 #if defined(UX_DEVICE_STANDALONE)
1072         ux_system_tasks_run();
1073         tx_thread_relinquish();
1074 #else
1075         /* Sleep so ThreadX on Win32 will delete this thread. */
1076         tx_thread_sleep(10);
1077 #endif
1078     }
1079 }
1080 
1081 
ux_test_ccid_icc_power_on(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1082 static UINT ux_test_ccid_icc_power_on(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1083 {
1084 UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER          *icc_power_on;
1085 UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER            *data_block;
1086     ux_test_callback_log(ux_test_ccid_icc_power_on, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1087     /* Access to command.  */
1088     icc_power_on = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1089     /* Access to data.  */
1090     data_block = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1091     /* bPowerSelect.  */
1092     icc_power_on->bPowerSelect;
1093     /* Update bStatus,bError.  */
1094     data_block->bStatus = UX_DEVICE_CLASS_CCID_ICC_ACTIVE;
1095     // data_block->bError = 0;
1096     /* Update data length (reply message header only).  */
1097     io_msg->ux_device_class_ccid_messages_rdr_to_pc_length = 10;
1098 #if defined(UX_DEVICE_STANDALONE)
1099     return(UX_STATE_NEXT);
1100 #else
1101     return(UX_SUCCESS);
1102 #endif
1103 }
ux_test_ccid_icc_power_off(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1104 static UINT ux_test_ccid_icc_power_off(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1105 {
1106 UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_OFF_HEADER         *cmd;
1107 UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER           *rsp;
1108     ux_test_callback_log(ux_test_ccid_icc_power_off, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1109     /* Access to command.  */
1110     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_OFF_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1111     /* Access to data.  */
1112     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1113     /* Update bStatus,bError.  */
1114     rsp->bStatus = UX_DEVICE_CLASS_CCID_ICC_INACTIVE;
1115     // rsp->bError = 0;
1116 #if defined(UX_DEVICE_STANDALONE)
1117     return(UX_STATE_NEXT);
1118 #else
1119     return(UX_SUCCESS);
1120 #endif
1121 }
ux_test_ccid_get_slot_status(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1122 static UINT ux_test_ccid_get_slot_status(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1123 {
1124 UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_SLOT_STATUS_HEADER       *cmd;
1125 UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER           *rsp;
1126     ux_test_callback_log(ux_test_ccid_get_slot_status, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1127     /* Access to command.  */
1128     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_SLOT_STATUS_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1129     /* Access to data.  */
1130     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1131     /* Update bStatus,bError.  */
1132     // rsp->bStatus = 0;
1133     // rsp->bError = 0;
1134     // rsp->bClockStatus = 0;
1135 #if defined(UX_DEVICE_STANDALONE)
1136     return(UX_STATE_NEXT);
1137 #else
1138     return(UX_SUCCESS);
1139 #endif
1140 }
ux_test_ccid_xfr_block(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1141 static UINT ux_test_ccid_xfr_block(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1142 {
1143 UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER             *cmd;
1144 UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER            *rsp;
1145 UCHAR                                                       *cmd_data;
1146 UCHAR                                                       *rsp_data;
1147 UCHAR                                                       i;
1148     ux_test_callback_log(ux_test_ccid_xfr_block, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1149     /* Access to command.  */
1150     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1151     /* Access to data.  */
1152     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1153     /* Access to data buffers.  */
1154     cmd_data = (UCHAR*)io_msg->ux_device_class_ccid_messages_pc_to_rdr + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
1155     rsp_data = (UCHAR*)io_msg->ux_device_class_ccid_messages_rdr_to_pc + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
1156 
1157     /* Time extension.  */
1158     // ux_device_class_ccid_time_extension(device_ccid, slot, 10);
1159 
1160 #if defined(UX_DEVICE_STANDALONE)
1161     switch(slot_tester[cmd->bSlot].state)
1162     {
1163     case SLOT_TESTER_STATE_START:
1164         slot_tester[cmd->bSlot].state = SLOT_TESTER_STATE_WAIT;
1165         return(UX_STATE_WAIT);
1166     case SLOT_TESTER_STATE_WAIT:
1167         return(UX_STATE_WAIT);
1168     case SLOT_TESTER_STATE_NEXT:
1169         slot_tester[cmd->bSlot].state = SLOT_TESTER_STATE_IDLE;
1170         break;
1171     default:
1172         slot_tester[cmd->bSlot].state = SLOT_TESTER_STATE_START;
1173         return(UX_STATE_WAIT);
1174     }
1175 #else
1176 
1177     /* Semaphore wait.  */
1178     tx_semaphore_get(&slot_tester[cmd->bSlot].semaphore, slot_tester[cmd->bSlot].timeout);
1179     /* Abort?  */
1180     if (slot_tester[cmd->bSlot].flags & SLOT_TESTER_FLAG_ABORT)
1181     {
1182         slot_tester[cmd->bSlot].flags &= ~SLOT_TESTER_FLAG_ABORT;
1183         return(UX_ERROR);
1184     }
1185 #endif
1186 
1187     /* Update bStatus,bError.  */
1188     // rsp->bStatus = 0;
1189     // rsp->bError = 0;
1190 
1191     /* Update data.  */
1192     for (i = 10; i < 64; i ++)
1193         rsp_data[i] = i;
1194 
1195     /* Update data length.  */
1196     UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 64-10);
1197     io_msg->ux_device_class_ccid_messages_rdr_to_pc_length = 64;
1198 
1199 #if defined(UX_DEVICE_STANDALONE)
1200     return(UX_STATE_NEXT);
1201 #else
1202     return(UX_SUCCESS);
1203 #endif
1204 }
ux_test_ccid_get_parameters(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1205 static UINT ux_test_ccid_get_parameters(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1206 {
1207 UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_PARAMETERS_HEADER        *cmd;
1208 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER            *rsp;
1209 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0                *t0;
1210 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1                *t1;
1211     ux_test_callback_log(ux_test_ccid_get_parameters, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1212     /* Access to command.  */
1213     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_PARAMETERS_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1214     /* Access to data.  */
1215     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1216     /* Parameters protocol.  */
1217     rsp->bProtocolNum = 0;
1218     if (rsp->bProtocolNum == 0)
1219     {
1220         t0 = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0 *)rsp;
1221         t0->bmFindexDindex = 0;
1222         /* ... */
1223     }
1224     else if (rsp->bProtocolNum == 1)
1225     {
1226         t1 = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1 *)rsp;
1227         t1->bmFindexDindex = 0;
1228         /* ... */
1229     }
1230     /* Update bStatus,bError.  */
1231     // rsp->bStatus = 0;
1232     // rsp->bError = 0;
1233     /* Update data length.  */
1234     UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 5);
1235     io_msg->ux_device_class_ccid_messages_rdr_to_pc_length = 5+10;
1236 #if defined(UX_DEVICE_STANDALONE)
1237     return(UX_STATE_NEXT);
1238 #else
1239     return(UX_SUCCESS);
1240 #endif
1241 }
ux_test_ccid_reset_parameters(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1242 static UINT ux_test_ccid_reset_parameters(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1243 {
1244 UX_DEVICE_CLASS_CCID_PC_TO_RDR_RESET_PARAMETERS_HEADER      *cmd;
1245 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER            *rsp;
1246 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0                *t0;
1247 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1                *t1;
1248     ux_test_callback_log(ux_test_ccid_reset_parameters, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1249     /* Access to command.  */
1250     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_RESET_PARAMETERS_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1251     /* Access to response.  */
1252     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1253     /* Parameters protocol.  */
1254     rsp->bProtocolNum = 0;
1255     if (rsp->bProtocolNum == 0)
1256     {
1257         t0 = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0 *)rsp;
1258         t0->bmFindexDindex = 0;
1259         /* ... */
1260     }
1261     else if (rsp->bProtocolNum == 1)
1262     {
1263         t1 = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1 *)rsp;
1264         t1->bmFindexDindex = 0;
1265         /* ... */
1266     }
1267     /* Update bStatus,bError.  */
1268     // rsp->bStatus = 0;
1269     // rsp->bError = 0;
1270     /* Update data length.  */
1271     UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 5);
1272     io_msg->ux_device_class_ccid_messages_rdr_to_pc_length = 5+10;
1273 #if defined(UX_DEVICE_STANDALONE)
1274     return(UX_STATE_NEXT);
1275 #else
1276     return(UX_SUCCESS);
1277 #endif
1278 }
ux_test_ccid_set_parameters(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1279 static UINT ux_test_ccid_set_parameters(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1280 {
1281 UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER        *cmd;
1282 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER            *rsp;
1283 UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0            *cmd_t0;
1284 UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1            *cmd_t1;
1285 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0                *rsp_t0;
1286 UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1                *rsp_t1;
1287     ux_test_callback_log(ux_test_ccid_set_parameters, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1288     /* Access to command.  */
1289     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1290     /* Access to response.  */
1291     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1292     if (rsp->bProtocolNum == 0)
1293     {
1294         cmd_t0 = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0 *)cmd;
1295         rsp_t0 = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0 *)rsp;
1296         /* ... */
1297     }
1298     else
1299     {
1300         cmd_t1 = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1 *)cmd;
1301         rsp_t1 = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1 *)rsp;
1302     }
1303     /* Update bStatus,bError.  */
1304     // rsp->bStatus = 0;
1305     // rsp->bError = 0;
1306     /* Update data length.  */
1307     UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 5);
1308     io_msg->ux_device_class_ccid_messages_rdr_to_pc_length = 5+10;
1309 #if defined(UX_DEVICE_STANDALONE)
1310     return(UX_STATE_NEXT);
1311 #else
1312     return(UX_SUCCESS);
1313 #endif
1314 }
ux_test_ccid_escape(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1315 static UINT ux_test_ccid_escape(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1316 {
1317 UX_DEVICE_CLASS_CCID_PC_TO_RDR_ESCAPE_HEADER            *cmd;
1318 UX_DEVICE_CLASS_CCID_RDR_TO_PC_ESCAPE_HEADER            *rsp;
1319 UCHAR                                                   *cmd_data;
1320 UCHAR                                                   *rsp_data;
1321     ux_test_callback_log(ux_test_ccid_escape, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1322     /* Access to command.  */
1323     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_ESCAPE_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1324     /* Access to data.  */
1325     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_ESCAPE_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1326     cmd_data = io_msg->ux_device_class_ccid_messages_pc_to_rdr + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
1327     rsp_data = io_msg->ux_device_class_ccid_messages_rdr_to_pc + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
1328     /* Update bStatus,bError.  */
1329     // rsp->bStatus = 0;
1330     // rsp->bError = 0;
1331     /* Update data length.  */
1332     UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 128);
1333     io_msg->ux_device_class_ccid_messages_rdr_to_pc_length = 128+10;
1334 #if defined(UX_DEVICE_STANDALONE)
1335     return(UX_STATE_NEXT);
1336 #else
1337     return(UX_SUCCESS);
1338 #endif
1339 }
ux_test_ccid_icc_clock(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1340 static UINT ux_test_ccid_icc_clock(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1341 {
1342 UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER             *cmd;
1343 UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER           *rsp;
1344     ux_test_callback_log(ux_test_ccid_icc_clock, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1345     /* Access to command.  */
1346     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1347     /* Access to data.  */
1348     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1349     /* Clock command.  */
1350     cmd->bClockCommand;
1351     /* Update bStatus,bError.  */
1352     // rsp->bStatus = 0;
1353     // rsp->bError = 0;
1354 #if defined(UX_DEVICE_STANDALONE)
1355     return(UX_STATE_NEXT);
1356 #else
1357     return(UX_SUCCESS);
1358 #endif
1359 }
ux_test_ccid_t0_apdu(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1360 static UINT ux_test_ccid_t0_apdu(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1361 {
1362 UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER               *cmd;
1363 UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER           *rsp;
1364     ux_test_callback_log(ux_test_ccid_t0_apdu, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1365     /* Access to command.  */
1366     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1367     /* Access to data.  */
1368     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1369     /* Changes.  */
1370     if (cmd->bmChanges & UX_DEVICE_CLASS_CCID_CHANGE_CLASS_ENVELOPE)
1371     {
1372         cmd->bClassEnvelope;
1373     }
1374     if (cmd->bmChanges & UX_DEVICE_CLASS_CCID_CHANGE_CLASS_GET_RESPONSE)
1375     {
1376         cmd->bClassGetResponse;
1377     }
1378     /* Update bStatus,bError.  */
1379     rsp->bStatus = 0;
1380     rsp->bError = 0;
1381 
1382 #if defined(UX_DEVICE_STANDALONE)
1383     return(UX_STATE_NEXT);
1384 #else
1385     return(UX_SUCCESS);
1386 #endif
1387 }
ux_test_ccid_secure(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1388 static UINT ux_test_ccid_secure(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1389 {
1390 UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_HEADER            *cmd;
1391 UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER        *rsp;
1392 UCHAR                                                   *cmd_data;
1393 UCHAR                                                   *rsp_data;
1394     ux_test_callback_log(ux_test_ccid_secure, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1395     /* Access to command.  */
1396     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1397     /* Access to data.  */
1398     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1399 
1400     cmd->wLevelParameter;
1401     rsp->bChainParameter;
1402 
1403     cmd_data = io_msg->ux_device_class_ccid_messages_pc_to_rdr + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
1404     rsp_data = io_msg->ux_device_class_ccid_messages_rdr_to_pc + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
1405 
1406     /* Update bStatus,bError.  */
1407     // rsp->bStatus = 0;
1408     // rsp->bError = 0;
1409     /* Update data length.  */
1410     UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 128/8);
1411     io_msg->ux_device_class_ccid_messages_rdr_to_pc_length = 128/8+10;
1412 #if defined(UX_DEVICE_STANDALONE)
1413     return(UX_STATE_NEXT);
1414 #else
1415     return(UX_SUCCESS);
1416 #endif
1417 }
ux_test_ccid_mechanical(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1418 static UINT ux_test_ccid_mechanical(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1419 {
1420 UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER            *cmd;
1421 UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER           *rsp;
1422     ux_test_callback_log(ux_test_ccid_mechanical, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1423     /* Access to command.  */
1424     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1425     /* Access to data.  */
1426     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1427     /* Update bStatus,bError.  */
1428     // rsp->bStatus = 0;
1429     // rsp->bError = 0;
1430 #if defined(UX_DEVICE_STANDALONE)
1431     return(UX_STATE_NEXT);
1432 #else
1433     return(UX_SUCCESS);
1434 #endif
1435 }
ux_test_ccid_abort(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1436 static UINT ux_test_ccid_abort(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1437 {
1438 UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT_HEADER                 *cmd;
1439 UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER           *rsp;
1440     /* Control request Abort.  */
1441     if (io_msg == UX_NULL)
1442     {
1443         ux_test_callback_log(ux_test_ccid_abort, UX_NULL);
1444         slot_tester[slot].flags |= SLOT_TESTER_FLAG_ABORT;
1445 #if defined(UX_DEVICE_STANDALONE)
1446         slot_tester[slot].state = SLOT_TESTER_STATE_NEXT;
1447         return(UX_STATE_NEXT);
1448 #else
1449         tx_semaphore_put(&slot_tester[slot].semaphore);
1450         return(UX_SUCCESS);
1451 #endif
1452     }
1453     /* Bulk OUT Abort.  */
1454     ux_test_callback_log(ux_test_ccid_abort, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1455     /* Access to command.  */
1456     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT_HEADER*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1457     /* Access to data.  */
1458     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1459     /* Update bStatus,bError.  */
1460     // rsp->bStatus = 0;
1461     // rsp->bError = 0;
1462 #if defined(UX_DEVICE_STANDALONE)
1463     return(UX_STATE_NEXT);
1464 #else
1465     return(UX_SUCCESS);
1466 #endif
1467 }
ux_test_ccid_set_data_rate_and_clock_frequency(ULONG slot,UX_DEVICE_CLASS_CCID_MESSAGES * io_msg)1468 static UINT ux_test_ccid_set_data_rate_and_clock_frequency(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*io_msg)
1469 {
1470 UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY        *cmd;
1471 UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY            *rsp;
1472 ULONG                                                                   data_rate;
1473 ULONG                                                                   clock;
1474     ux_test_callback_log(ux_test_ccid_set_data_rate_and_clock_frequency, io_msg->ux_device_class_ccid_messages_pc_to_rdr);
1475     /* Access to command.  */
1476     cmd = (UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY*)io_msg->ux_device_class_ccid_messages_pc_to_rdr;
1477     /* Access to data.  */
1478     rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY*)io_msg->ux_device_class_ccid_messages_rdr_to_pc;
1479     data_rate = UX_DEVICE_CLASS_CCID_PC_TO_RDR_CLOCK_FREQUENCY_GET(cmd);
1480     clock = UX_DEVICE_CLASS_CCID_PC_TO_RDR_DATA_RATE_GET(cmd);
1481     /* Update bStatus,bError.  */
1482     // rsp->bStatus = 0;
1483     // rsp->bError = 0;
1484     /* Update response data rate and clock.  */
1485     UX_DEVICE_CLASS_CCID_RDR_TO_PC_CLOCK_FREQUENCY_SET(rsp, clock);
1486     UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_SET(rsp, data_rate);
1487 #if defined(UX_DEVICE_STANDALONE)
1488     return(UX_STATE_NEXT);
1489 #else
1490     return(UX_SUCCESS);
1491 #endif
1492 }
1493