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