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