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