1 #include "tx_api.h"
2 #include "nx_api.h"
3 #include "netxtestcontrol.h"
4
5 extern void test_control_return(UINT);
6
7 #if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN)
8 #include "nx_rtp_sender.h"
9
10 #define DEMO_STACK_SIZE 4096
11
12 #define NUM_PACKETS 10
13 #define PACKET_SIZE 1536
14 #define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET)))
15
16 #define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4)
17 #define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5)
18 #define RTP_CLIENT_RTP_PORT 6002
19 #define RTP_CLIENT_RTCP_PORT 6003
20 #define RTP_PAYLOAD_TYPE 96
21 #define CNAME "AzureRTOS@microsoft.com"
22
23 /* Define test data. */
24 #define TEST_TIMESTAMP 1234
25 #define TEST_MSW 123
26 #define TEST_LSW 456
27
28 /* Define the number of tests to do */
29 #define TEST_CYCLES 4
30
31 /* Define jpeg test data */
32 #define TEST_JPEG_Q_TABLE_SIZE 64
33 #define TEST_JPEG_Q_TABLE_START_POS (2 + 2 + 0x10 + 5)
34 #define TEST_JPEG_IMAGE_DATA_START_POS (TEST_JPEG_Q_TABLE_START_POS + TEST_JPEG_Q_TABLE_SIZE + 2 + 0x11 + 2 + 0x0C)
35 static UCHAR test_rtp_packet_data[] = { 0xFF, 0xD8, /* JPEG file header */
36
37 /* APP0 */
38 0xFF, 0xE0, 0x00, 0x10,
39 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00,
40
41 /* Quntization tables */
42 0xFF, 0xDB, 0x00, 0x43,
43 0x00,
44 0x07, 0x05, 0x05, 0x06, 0x05, 0x04, 0x07, 0x06, 0x06, 0x06, 0x08, 0x07, 0x07, 0x08, 0x0B, 0x12,
45 0x0B, 0x0B, 0x0A, 0x0A, 0x0B, 0x16, 0x0F, 0x10, 0x0D, 0x12, 0x1A, 0x16, 0x1B, 0x1A, 0x19, 0x16,
46 0x19, 0x18, 0x1C, 0x20, 0x28, 0x22, 0x1C, 0x1E, 0x26, 0x1E, 0x18, 0x19, 0x23, 0x30, 0x24, 0x26,
47 0x2A, 0x2B, 0x2D, 0x2E, 0x2D, 0x1B, 0x22, 0x32, 0x35, 0x31, 0x2C, 0x35, 0x28, 0x2C, 0x2D, 0x2C,
48
49 /* Baseline information */
50 0xFF, 0xC0, 0x00, 0x11,
51 0x08, 0x00, 0x84, 0x00, 0x84, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
52
53 0xFF, 0xDA, /* JPEG image data begin marker */
54 0x00, 0x0C,
55 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, /* Data header */
56
57 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* Test data */
58 0xFF, 0xD9 /* JPEG image data end marker*/
59 }; /* test_rtp_packet_data */
60
61 #define TEST_LONG_JPEG_Q_TABLE_1_START_POS (2 + 2 + 0x10 + 5)
62 #define TEST_LONG_JPEG_Q_TABLE_2_START_POS (TEST_LONG_JPEG_Q_TABLE_1_START_POS + TEST_JPEG_Q_TABLE_SIZE + 5)
63 #define TEST_LONG_JPEG_BASELINE_INFO_START_POS (TEST_LONG_JPEG_Q_TABLE_2_START_POS + TEST_JPEG_Q_TABLE_SIZE)
64 #define TEST_LONG_JPEG_HUFFMAN_TABLE_START_POS (TEST_LONG_JPEG_BASELINE_INFO_START_POS + 2 + 0x11)
65 #define TEST_LONG_JPEG_IMAGE_DATA_START_POS (TEST_LONG_JPEG_HUFFMAN_TABLE_START_POS + 2 + 0x1C + 2 + 0x3E + 2 + 0x19 + 2 + 0x23 + 2 + 0x0C)
66 static UCHAR test_long_rtp_packet_data[] = { 0xFF, 0xD8, /* JPEG file header */
67
68 /* APP0 */
69 0xFF, 0xE0, 0x00, 0x10,
70 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00,
71
72 /* Quntization tables */
73 0xFF, 0xDB, 0x00, 0x43,
74 0x00,
75 0x07, 0x05, 0x05, 0x06, 0x05, 0x04, 0x07, 0x06, 0x06, 0x06, 0x08, 0x07, 0x07, 0x08, 0x0B, 0x12,
76 0x0B, 0x0B, 0x0A, 0x0A, 0x0B, 0x16, 0x0F, 0x10, 0x0D, 0x12, 0x1A, 0x16, 0x1B, 0x1A, 0x19, 0x16,
77 0x19, 0x18, 0x1C, 0x20, 0x28, 0x22, 0x1C, 0x1E, 0x26, 0x1E, 0x18, 0x19, 0x23, 0x30, 0x24, 0x26,
78 0x2A, 0x2B, 0x2D, 0x2E, 0x2D, 0x1B, 0x22, 0x32, 0x35, 0x31, 0x2C, 0x35, 0x28, 0x2C, 0x2D, 0x2C,
79 0xFF, 0xDB, 0x00, 0x43,
80 0x01,
81 0x07, 0x08, 0x08, 0x0B, 0x09, 0x0B, 0x15, 0x0B, 0x0B, 0x15, 0x2C, 0x1D, 0x19, 0x1D, 0x2C, 0x2C,
82 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
83 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
84 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
85
86 /* Baseline information */
87 0xFF, 0xC0, 0x00, 0x11,
88 0x08, 0x00, 0x84, 0x00, 0x84, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
89
90 /* Huffman tables */
91 0xFF, 0xC4, 0x00, 0x1C,
92 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x01, 0x02, 0x08,
94 0xFF, 0xC4, 0x00, 0x3E,
95 0x10, 0x00, 0x02, 0x01, 0x03, 0x02, 0x03, 0x05, 0x04, 0x06, 0x08, 0x06, 0x03, 0x00, 0x00, 0x00,
96 0x00, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x06, 0x21, 0x31, 0x13, 0x41, 0x51, 0x61,
97 0x71, 0x07, 0x22, 0x32, 0x72, 0x14, 0x42, 0x81, 0x91, 0xA1, 0xC1, 0x23, 0x33, 0x43, 0x52, 0x62,
98 0xB1, 0xD1, 0xE1, 0x15, 0x24, 0x34, 0x92, 0xA2, 0xF0, 0x44, 0xB2, 0xF1,
99 0xFF, 0xC4, 0x00, 0x19,
100 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x02, 0x03, 0x01, 0x04, 0x05,
102 0xFF, 0xC4, 0x00, 0x23,
103 0x11, 0x00, 0x02, 0x02, 0x02, 0x01, 0x03, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x01, 0x02, 0x11, 0x03, 0x31, 0x21, 0x12, 0x22, 0x41, 0x04, 0x13, 0x32, 0x51, 0x61,
105 0xF0,
106
107 0xFF, 0xDA, /* JPEG image data begin marker */
108 0x00, 0x0C,
109 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, /* Data header */
110
111 /* Test data */
112 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
113 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
114 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
115 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
116 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
117 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
118 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
119 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
120 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
121 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
122 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
123 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
124 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
125 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
126 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
127 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
128 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
129 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
130 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
131 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
132 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
133 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
134 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
135 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
136 0xFF, 0xD9 /* JPEG image data end marker*/
137 }; /* test_rtp_packet_data */
138
139 /* Define the ThreadX object control blocks... */
140
141 static TX_THREAD ntest_0;
142 static TX_THREAD ntest_1;
143
144 static NX_PACKET_POOL pool_0;
145 static NX_IP ip_0;
146 static NX_IP ip_1;
147 static NX_UDP_SOCKET rtp_client_socket;
148
149 static TX_SEMAPHORE semaphore_test_0_done;
150 static TX_SEMAPHORE semaphore_test_1_done;
151
152 /* Define rtp sender control block. */
153 static NX_RTP_SENDER rtp_0;
154 static NX_RTP_SESSION rtp_session_0;
155 static UINT rtp_port;
156 static UINT rtcp_port;
157
158
159 /* Define thread prototypes. */
160
161 static void ntest_0_entry(ULONG thread_input);
162 static void ntest_1_entry(ULONG thread_input);
163 extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
164 extern VOID _nx_ram_network_driver_256(NX_IP_DRIVER *driver_req_ptr);
165 extern void test_control_return(UINT status);
166
167 #ifdef CTEST
test_application_define(void * first_unused_memory)168 VOID test_application_define(void *first_unused_memory)
169 #else
170 void netx_rtp_session_jpeg_send_test_application_define(void *first_unused_memory)
171 #endif
172 {
173
174 CHAR *pointer;
175 UINT status;
176
177 /* Print out test information banner. */
178 printf("NetX Test: RTP Session JPEG Send Test............................................");
179
180 /* Setup the working pointer. */
181 pointer = (CHAR *)first_unused_memory;
182
183 /* Create the server thread. */
184 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
185 pointer, DEMO_STACK_SIZE,
186 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
187
188 pointer = pointer + DEMO_STACK_SIZE;
189
190 /* Create the client thread. */
191 tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
192 pointer, DEMO_STACK_SIZE,
193 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
194
195 pointer = pointer + DEMO_STACK_SIZE;
196
197 /* Initialize the NetX system. */
198 nx_system_initialize();
199
200 /* Create a packet pool. */
201 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE);
202 pointer = pointer + PACKET_POOL_SIZE;
203 CHECK_STATUS(0, status);
204
205 /* Create server IP instance. */
206 status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
207 pointer, 2048, 1);
208 pointer = pointer + 2048;
209 CHECK_STATUS(0, status);
210
211 /* Create client IP instance. */
212 status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
213 pointer, 2048, 1);
214 pointer = pointer + 2048;
215 CHECK_STATUS(0, status);
216
217 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
218 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
219 pointer = pointer + 1024;
220 CHECK_STATUS(0, status);
221
222 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
223 status = nx_arp_enable(&ip_1, (void *) pointer, 1024);
224 pointer = pointer + 1024;
225 CHECK_STATUS(0, status);
226
227 /* Enable UDP processing for both IP instances. */
228 status = nx_udp_enable(&ip_0);
229 CHECK_STATUS(0, status);
230 status = nx_udp_enable(&ip_1);
231 CHECK_STATUS(0, status);
232
233 /* Create semaphores for test done notification */
234 tx_semaphore_create(&semaphore_test_0_done, "semaphore test 0", 0);
235 tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0);
236 }
237
validate_rtp_jpeg_data(UCHAR * data,UINT data_length)238 static UINT validate_rtp_jpeg_data(UCHAR *data, UINT data_length)
239 {
240 UINT i;
241 ULONG size_offset;
242 UCHAR *data_ptr = data;
243
244
245 /* The first byte is always 0 */
246 if (data_ptr[0] != 0x00)
247 {
248 return(NX_NOT_SUCCESSFUL);
249 }
250 data_ptr++;
251
252 /* Compute size_offset and compare with target offset */
253 size_offset = (ULONG)(data_ptr[0] << 16 | data_ptr[1] << 8 | data_ptr[2]);
254 if (size_offset != 0)
255 {
256 return(NX_NOT_SUCCESSFUL);
257 }
258 data_ptr += 3;
259
260 /* Check rtp/jpeg type, for YUV420 (0x21 in jpeg image), type shall be 0 */
261 if (data_ptr[0] != 0x00)
262 {
263 return(NX_NOT_SUCCESSFUL);
264 }
265 data_ptr++;
266
267 /* Check Q value */
268 if (data_ptr[0] != 0xFF)
269 {
270 return(NX_NOT_SUCCESSFUL);
271 }
272 data_ptr++;
273
274 /* Check jpeg image width and height */
275 if ((data_ptr[0] != (0x84 >> 3)) || (data_ptr[1] != (0x84 >> 3)))
276 {
277 return(NX_NOT_SUCCESSFUL);
278 }
279 data_ptr += 2;
280
281 /* Check quantization table header */
282 if (data_ptr[0] != 0x00 || data_ptr[1] != 0x00 || data_ptr[2] != 0x00 || data_ptr[3] != 0x40)
283 {
284 return(NX_NOT_SUCCESSFUL);
285 }
286 data_ptr += 4;
287
288 /* Check the quantization table */
289 for (i = 0; i < TEST_JPEG_Q_TABLE_SIZE; i++)
290 {
291 if (data_ptr[i] != test_rtp_packet_data[TEST_JPEG_Q_TABLE_START_POS + i])
292 {
293 return(NX_NOT_SUCCESSFUL);
294 }
295 }
296 data_ptr += TEST_JPEG_Q_TABLE_SIZE;
297
298 /* Check JPEG image data */
299 i = 0;
300 while (data_ptr < (data + data_length))
301 {
302 if (*data_ptr != test_rtp_packet_data[TEST_JPEG_IMAGE_DATA_START_POS + i])
303 {
304 return(NX_NOT_SUCCESSFUL);
305 }
306
307 i++;
308 data_ptr++;
309 }
310
311 return(NX_SUCCESS);
312 }
313
validate_long_rtp_jpeg_data(UCHAR * data,UINT data_length)314 static UINT validate_long_rtp_jpeg_data(UCHAR *data, UINT data_length)
315 {
316 UINT i;
317 ULONG size_offset;
318 UCHAR *data_ptr = data;
319 static ULONG offset = 0;
320
321 /* The first byte is always 0 */
322 if (data_ptr[0] != 0x00)
323 {
324 return(NX_NOT_SUCCESSFUL);
325 }
326 data_ptr++;
327
328 /* Compute size_offset and compare with target offset */
329 size_offset = (ULONG)(data_ptr[0] << 16 | data_ptr[1] << 8 | data_ptr[2]);
330 if (size_offset != offset)
331 {
332 return(NX_NOT_SUCCESSFUL);
333 }
334 data_ptr += 3;
335
336 /* Check rtp/jpeg type, for YUV422 (0x22 in jpeg image), type shall be 1 */
337 if (data_ptr[0] != 0x01)
338 {
339 return(NX_NOT_SUCCESSFUL);
340 }
341 data_ptr++;
342
343 /* Check Q value */
344 if (data_ptr[0] != 0xFF)
345 {
346 return(NX_NOT_SUCCESSFUL);
347 }
348 data_ptr++;
349
350 /* Check jpeg image width and height */
351 if ((data_ptr[0] != (0x84 >> 3)) || (data_ptr[1] != (0x84 >> 3)))
352 {
353 return(NX_NOT_SUCCESSFUL);
354 }
355 data_ptr += 2;
356
357 /* Only first fragmented packet contains quantization tables */
358 if (offset == 0)
359 {
360
361 /* Check quantization table header */
362 if (data_ptr[0] != 0x00 || data_ptr[1] != 0x00 || data_ptr[2] != 0x00 || data_ptr[3] != 0x80)
363 {
364 return(NX_NOT_SUCCESSFUL);
365 }
366 data_ptr += 4;
367
368 /* Check both 2 quantization tables */
369 for (i = 0; i < TEST_JPEG_Q_TABLE_SIZE; i++)
370 {
371 if (data_ptr[i] != test_long_rtp_packet_data[TEST_LONG_JPEG_Q_TABLE_1_START_POS + i])
372 {
373 return(NX_NOT_SUCCESSFUL);
374 }
375
376 if (data_ptr[TEST_JPEG_Q_TABLE_SIZE + i] != test_long_rtp_packet_data[TEST_LONG_JPEG_Q_TABLE_2_START_POS + i])
377 {
378 return(NX_NOT_SUCCESSFUL);
379 }
380 }
381 data_ptr += TEST_JPEG_Q_TABLE_SIZE * 2;
382 }
383
384 /* Check JPEG image data */
385 while (data_ptr < (data + data_length))
386 {
387 if (*data_ptr != test_long_rtp_packet_data[TEST_LONG_JPEG_IMAGE_DATA_START_POS + offset])
388 {
389 return(NX_NOT_SUCCESSFUL);
390 }
391
392 offset++;
393 data_ptr++;
394 }
395
396 return(NX_SUCCESS);
397 }
398
399 /* Define server threads. */
ntest_0_entry(ULONG thread_input)400 static void ntest_0_entry(ULONG thread_input)
401 {
402 UINT status;
403 NXD_ADDRESS client_ip_address;
404 NX_PACKET *send_packet;
405 UINT time_start;
406 ULONG temp_socket_id;
407
408
409 /* Create RTP sender. */
410 status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1);
411 CHECK_STATUS(0, status);
412
413 /* Get the udp port pair for rtp and rtcp */
414 status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port);
415 CHECK_STATUS(0, status);
416
417 /* Setup rtp sender session. */
418 client_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
419 client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS;
420 status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE,
421 0, &client_ip_address,
422 RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT);
423 CHECK_STATUS(0, status);
424
425 /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once.
426 To make a stable test result, wait for a tick here to avoid this situation. */
427 tx_thread_sleep(1);
428
429 /* ---- Test cycle 1 ---- */
430
431 /* Send jpeg data. */
432 status = nx_rtp_sender_session_jpeg_send(&rtp_session_0, test_rtp_packet_data, sizeof(test_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1);
433 CHECK_STATUS(NX_SUCCESS, status);
434
435 /* ---- Test cycle 2 ~ 4 ---- */
436
437 /* Send jpeg data. */
438 status = nx_rtp_sender_session_jpeg_send(&rtp_session_0, test_long_rtp_packet_data, sizeof(test_long_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1);
439 CHECK_STATUS(NX_SUCCESS, status);
440
441 /* Wait for the check in test thread 1 done. */
442 status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE);
443 CHECK_STATUS(0, status);
444
445 /* Delete and release resources */
446 status = nx_rtp_sender_session_delete(&rtp_session_0);
447 CHECK_STATUS(0, status);
448
449 status = nx_rtp_sender_delete(&rtp_0);
450 CHECK_STATUS(0, status);
451
452 /* Put the semaphore to notify thread 1 it is fine to check resource leakage. */
453 tx_semaphore_put(&semaphore_test_0_done);
454 }
455
456 /* Define the client threads. */
ntest_1_entry(ULONG thread_input)457 static void ntest_1_entry(ULONG thread_input)
458 {
459 NX_PACKET *received_packet;
460 UINT j;
461 UINT status;
462 UCHAR *data;
463 UINT test_data_pos = 0;
464 ULONG offset = 0;
465
466
467 /* Create the rtp client socket. */
468 status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
469 CHECK_STATUS(0, status);
470
471 status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE);
472 CHECK_STATUS(0, status);
473
474 for (UINT i = 0; i < TEST_CYCLES; i++)
475 {
476
477 /* Receive rtp data packet. */
478 status = nx_udp_socket_receive(&rtp_client_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND);
479 CHECK_STATUS(0, status);
480
481 /* Validate RTP payload data */
482 data = received_packet -> nx_packet_prepend_ptr;
483
484 /* Check RTP version byte */
485 CHECK_STATUS(0x80, *data);
486
487 /* Move to check RTP data byte for payload type with marker */
488 data++;
489 if (i == 1 || i == 2)
490 {
491 CHECK_STATUS((RTP_PAYLOAD_TYPE), *data);
492 }
493 else
494 {
495 CHECK_STATUS((NX_RTP_HEADER_MARKER_BIT | RTP_PAYLOAD_TYPE), *data);
496 }
497
498 /* Move to check RTP data bytes for sequence number */
499 data++;
500 CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1]));
501
502 /* Move to check RTP data bytes for time stamp */
503 data += 2;
504 CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]));
505
506 /* Move to check RTP data bytes for ssrc */
507 data += 4;
508 CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]));
509
510 /* Move to check RTP data bytes for data payload */
511 data += 4;
512 if (i == 0)
513 {
514 status = validate_rtp_jpeg_data(data, received_packet -> nx_packet_length - 12);
515 CHECK_STATUS(NX_SUCCESS, status);
516 }
517 else if (i >= 1 && i <= 3)
518 {
519 status = validate_long_rtp_jpeg_data(data, received_packet -> nx_packet_length - 12);
520 if (status)
521 CHECK_STATUS(NX_SUCCESS, status);
522 }
523
524 /* Release the receive packet when the check finishes. */
525 nx_packet_release(received_packet);
526 }
527
528 /* Set the flag to notify test thread 0 that the check finishes. */
529 tx_semaphore_put(&semaphore_test_1_done);
530
531 /* Wait for the check in test thread 0 done. */
532 status = tx_semaphore_get(&semaphore_test_0_done, 5 * NX_IP_PERIODIC_RATE);
533 CHECK_STATUS(0, status);
534
535 /* Check if there is memory leak. */
536 CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available);
537
538 /* Return the test result. */
539 printf("SUCCESS!\n");
540 test_control_return(0);
541 }
542
543 #else
544
545 #ifdef CTEST
test_application_define(void * first_unused_memory)546 VOID test_application_define(void *first_unused_memory)
547 #else
548 void netx_rtp_session_jpeg_send_test_application_define(void *first_unused_memory)
549 #endif
550 {
551
552 /* Print out test information banner. */
553 printf("NetX Test: RTP Session JPEG Send Test............................................N/A\n");
554
555 test_control_return(3);
556 }
557 #endif
558
559