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