1 /* This test the case where a LINK DOWN event is received while transfers are
2 ongoing. */
3
4 #include "usbx_ux_test_cdc_ecm.h"
5 #include "ux_device_stack.h"
6
7 static ULONG global_basic_test_num_writes_host;
8 static ULONG global_basic_test_num_reads_host;
9
10 static ULONG global_basic_test_num_writes_device;
11 static ULONG global_basic_test_num_reads_device;
12
13 static UCHAR host_waiting_for_link_down;
14 static UCHAR host_waiting_for_link_up;
15
16 /* Define what the initial system looks like. */
17 #ifdef CTEST
test_application_define(void * first_unused_memory)18 void test_application_define(void *first_unused_memory)
19 #else
20 void usbx_cdc_ecm_link_down_while_ongoing_transfers_test_application_define(void *first_unused_memory)
21 #endif
22 {
23
24 /* Inform user. */
25 printf("Running CDC-ECM Host Link Down While Ongoing Transfers Test......... ");
26
27 stepinfo("\n");
28
29 ux_test_cdc_ecm_initialize(first_unused_memory);
30 }
31
basic_test_host()32 static void basic_test_host()
33 {
34
35 UINT num_iters;
36 UINT i;
37
38 /*** Basic test - no transfers going on. ***/
39 stepinfo("Basic test - no transfers going on.\n");
40
41 /* Now wait for the link to be down. */
42 host_waiting_for_link_down = 1;
43 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN));
44
45 /* Wait for everything to get cleaned up. */
46 tx_thread_sleep(MS_TO_TICK(1000));
47
48 /* Now wait for the link to be up. */
49 host_waiting_for_link_up = 1;
50 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP));
51
52 /* Run that basic test again. */
53 for (num_iters = 0; num_iters < 10; num_iters++)
54 {
55
56 for (i = 0; i < 10; i++)
57 write_packet_udp(&udp_socket_host, &packet_pool_host, DEVICE_IP_ADDRESS, DEVICE_SOCKET_PORT_UDP, global_basic_test_num_writes_host++, "host");
58
59 for (i = 0; i < 10; i++)
60 read_packet_udp(&udp_socket_host, global_basic_test_num_reads_host++, "host");
61 }
62
63 /* Wait for all transfers to complete. */
64 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_host, 100));
65 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_device, 100));
66 }
67
basic_test_device()68 static void basic_test_device()
69 {
70
71 UINT num_iters;
72 UINT i;
73
74 /*** Basic test. ***/
75
76 /* Wait for host to wait for link down. */
77 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_waiting_for_link_down, 1));
78 host_waiting_for_link_down = 0;
79
80 /* Now set the link to down. */
81 ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_DOWN);
82
83 /* Wait for host to wait for link up. */
84 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_waiting_for_link_up, 1));
85 host_waiting_for_link_up = 0;
86
87 /* Now set the link to up. */
88 ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP);
89
90 /* Now do basic test. */
91 for (num_iters = 0; num_iters < 10; num_iters++)
92 {
93
94 for (i = 0; i < 10; i++)
95 write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, global_basic_test_num_writes_device++, "device");
96
97 for (i = 0; i < 10; i++)
98 read_packet_udp(&udp_socket_device, global_basic_test_num_reads_device++, "device");
99 }
100
101 /* Wait for all transfers to complete. */
102 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_host, 100));
103 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_device, 100));
104 }
105
106 #define NUM_WRITES 500
107 #define NUM_WRITES_BEFORE_LINK_DOWN 10
108 #define MAX_WRITE_WHILE_LINK_DOWN (NUM_WRITES - NUM_WRITES_BEFORE_LINK_DOWN)
109
ongoing_writes_test_host()110 static void ongoing_writes_test_host()
111 {
112
113 UINT i;
114 UINT pre_write_fail_num_packet_pool_packets_available;
115 UINT num_writes = 0;
116
117 /*** Link down when there are queued writes, and we try to add writes. ***/
118 stepinfo("Ongoing writes test.\n");
119
120 pre_write_fail_num_packet_pool_packets_available = packet_pool_host.nx_packet_pool_available;
121
122 /* We expect some errors. */
123 UX_TEST_ACTION error_match_action = create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_CDC_ECM_LINK_STATE_DOWN_ERROR);
124 ux_test_add_action_to_main_list_multiple(error_match_action, MAX_WRITE_WHILE_LINK_DOWN);
125
126 /* Queue up some writes - device isn't going to read them, so they stay queued. */
127 for (i = 0; i < NUM_WRITES; i++)
128 {
129
130 /* Write packet. */
131 write_packet_udp(&udp_socket_host, &packet_pool_host, DEVICE_IP_ADDRESS, DEVICE_SOCKET_PORT_UDP, num_writes++, "host");
132
133 /* Have we queued 10 packets? */
134 if (i == NUM_WRITES_BEFORE_LINK_DOWN)
135 {
136
137 /* Set the link to down. The _hope_ here is to have the CDC-ECM thread
138 process the link down while we're still writing packets. This
139 should be improved in the future. I don't want to be the poor
140 SOB that has to do it!
141
142 We cheat here by calling a device API from the host. */
143 ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_DOWN);
144
145 while (cdc_ecm_host->ux_host_class_cdc_ecm_link_state != UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN)
146 tx_thread_sleep(10);
147 }
148 }
149
150 /* Make sure everything is ok. */
151 UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN);
152 NX_PACKET_POOL *packet_pool_host_local = &packet_pool_host;
153 UX_HOST_CLASS_CDC_ECM *cdc_ecm_host_local = cdc_ecm_host;
154 UX_TEST_ASSERT(packet_pool_host.nx_packet_pool_available == pre_write_fail_num_packet_pool_packets_available);
155
156 /* Make sure at least one error was reported. */
157 UX_TEST_ASSERT(ux_test_get_num_actions_left() != 90);
158
159 /* Now clear the error match actions out. */
160 ux_test_clear_main_list_actions();
161
162 /* Run that basic test again. */
163
164 /* Now wait for the link to be up. */
165 host_waiting_for_link_up = 1;
166 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP));
167
168 cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
169 }
170
ongoing_writes_test_device()171 static void ongoing_writes_test_device()
172 {
173
174 /*** Ongoing writes test. ***/
175
176 /* The host is gonna do all the work. At some point, he'll want the link back
177 up to run the basic test again. */
178 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_waiting_for_link_up, 1));
179
180 /* Set link to up. */
181 ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP);
182
183 /* Now do basic test. */
184 cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
185 }
186
post_init_host()187 static void post_init_host()
188 {
189
190 //basic_test_host();
191 ongoing_writes_test_host();
192 }
193
post_init_device(ULONG input)194 static void post_init_device(ULONG input)
195 {
196
197 //basic_test_device();
198 ongoing_writes_test_device();
199 }
200