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 24
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_VIDEO 96
21 #define RTP_PAYLOAD_TYPE_AUDIO 97
22 #define CNAME "AzureRTOS@microsoft.com"
23
24 /* Define test data. */
25 #define TEST_TIMESTAMP 1234
26 #define TEST_MSW 123
27 #define TEST_LSW 456
28 #define TEST_TIME_DURATION (6 * TX_TIMER_TICKS_PER_SECOND)
29
30 static UCHAR test_rtp_packet_data[] = "test rtp packet data";
31
32 /* Define the ThreadX object control blocks... */
33
34 static TX_THREAD ntest_0;
35 static TX_THREAD ntest_1;
36
37 static NX_PACKET_POOL pool_0;
38 static NX_IP ip_0;
39 static NX_IP ip_1;
40 static NX_UDP_SOCKET rtcp_client_socket;
41
42 /* Define rtp sender control block. */
43 static NX_RTP_SENDER rtp_0;
44 static NX_RTP_SESSION rtp_session_0;
45 static NX_RTP_SESSION rtp_session_1;
46 static NX_RTP_SESSION rtp_session_2;
47
48 /* Define the counters used in the test application... */
49 static UINT rtcp_packet_counter = 0;
50
51 /* Define thread prototypes. */
52
53 static void ntest_0_entry(ULONG thread_input);
54 static void ntest_1_entry(ULONG thread_input);
55 extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
56 extern void test_control_return(UINT status);
57
58 #ifdef CTEST
test_application_define(void * first_unused_memory)59 VOID test_application_define(void *first_unused_memory)
60 #else
61 void netx_rtcp_basic_test_application_define(void *first_unused_memory)
62 #endif
63 {
64
65 CHAR *pointer;
66 UINT status;
67
68 /* Print out test information banner. */
69 printf("NetX Test: RTCP Basic Test............................................");
70
71 /* Setup the working pointer. */
72 pointer = (CHAR *) first_unused_memory;
73
74 /* Create the server thread. */
75 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
76 pointer, DEMO_STACK_SIZE,
77 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
78
79 pointer = pointer + DEMO_STACK_SIZE;
80
81 /* Create the client thread. */
82 tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
83 pointer, DEMO_STACK_SIZE,
84 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
85
86 pointer = pointer + DEMO_STACK_SIZE;
87
88 /* Initialize the NetX system. */
89 nx_system_initialize();
90
91 /* Create a packet pool. */
92 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE);
93 pointer = pointer + PACKET_POOL_SIZE;
94 CHECK_STATUS(0, status);
95
96 /* Create server IP instance. */
97 status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
98 pointer, 2048, 1);
99 pointer = pointer + 2048;
100 CHECK_STATUS(0, status);
101
102 /* Create client IP instance. */
103 status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
104 pointer, 2048, 1);
105 pointer = pointer + 2048;
106 CHECK_STATUS(0, status);
107
108 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
109 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
110 pointer = pointer + 1024;
111 CHECK_STATUS(0, status);
112
113 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
114 status = nx_arp_enable(&ip_1, (void *) pointer, 1024);
115 pointer = pointer + 1024;
116 CHECK_STATUS(0, status);
117
118 /* Enable UDP processing for both IP instances. */
119 status = nx_udp_enable(&ip_0);
120 CHECK_STATUS(0, status);
121 status = nx_udp_enable(&ip_1);
122 CHECK_STATUS(0, status);
123 }
124
125 /* Define server threads. */
ntest_0_entry(ULONG thread_input)126 static void ntest_0_entry(ULONG thread_input)
127 {
128 UINT status;
129 NXD_ADDRESS client_ip_address;
130 NX_PACKET *send_packet;
131 UINT time_start;
132
133 /* Create RTP sender. */
134 status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1);
135 CHECK_STATUS(0, status);
136 rtp_session_0.nx_rtp_session_ssrc = 11478;
137
138 /* Setup rtp sender session. */
139 client_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
140 client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS;
141 status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE_VIDEO,
142 0, &client_ip_address,
143 RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT);
144 CHECK_STATUS(0, status);
145
146 status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_1, RTP_PAYLOAD_TYPE_AUDIO,
147 0, &client_ip_address,
148 RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT);
149 CHECK_STATUS(0, status);
150
151 status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_2, RTP_PAYLOAD_TYPE_AUDIO,
152 0, &client_ip_address,
153 RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT);
154 CHECK_STATUS(0, status);
155
156 /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once.
157 To make a stable test result, wait for a tick here to avoid this situation. */
158 tx_thread_sleep(1);
159
160 time_start = tx_time_get();
161
162 while(tx_time_get() - time_start < TEST_TIME_DURATION)
163 {
164 /* Allocate a packet */
165 status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE);
166 CHECK_STATUS(0, status);
167
168 /* Copy payload data into the packet. */
169 status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE);
170 CHECK_STATUS(0, status);
171
172 status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1);
173
174 CHECK_STATUS(0, status);
175 }
176
177 /* Check if there is memory leak. */
178 CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available);
179
180 /* Check rtcp packet count. */
181 CHECK_STATUS(TEST_TIME_DURATION / (TX_TIMER_TICKS_PER_SECOND * NX_RTCP_INTERVAL) + 1, rtcp_packet_counter);
182
183 status = nx_rtp_sender_session_delete(&rtp_session_2);
184 CHECK_STATUS(0, status);
185
186 status = nx_rtp_sender_session_delete(&rtp_session_1);
187 CHECK_STATUS(0, status);
188
189 status = nx_rtp_sender_session_delete(&rtp_session_0);
190 CHECK_STATUS(0, status);
191
192 /* Return the test result. */
193 printf("SUCCESS!\n");
194 test_control_return(0);
195 }
196
197 /* Define the client threads. */
ntest_1_entry(ULONG thread_input)198 static void ntest_1_entry(ULONG thread_input)
199 {
200 NX_PACKET *received_packet;
201 UINT status;
202
203 /* Create the rtp client socket. */
204 status = nx_udp_socket_create(&ip_1, &rtcp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
205 CHECK_STATUS(0, status);
206
207 status = nx_udp_socket_bind(&rtcp_client_socket, RTP_CLIENT_RTCP_PORT, NX_IP_PERIODIC_RATE);
208 CHECK_STATUS(0, status);
209
210 while(nx_udp_socket_receive(&rtcp_client_socket, &received_packet, (NX_RTCP_INTERVAL + 1) * TX_TIMER_TICKS_PER_SECOND) == NX_SUCCESS)
211 {
212 rtcp_packet_counter++;;
213 nx_packet_release(received_packet);
214 }
215 }
216
217 #else
218
219 #ifdef CTEST
test_application_define(void * first_unused_memory)220 VOID test_application_define(void *first_unused_memory)
221 #else
222 void netx_rtcp_basic_test_application_define(void *first_unused_memory)
223 #endif
224 {
225
226 /* Print out test information banner. */
227 printf("NetX Test: RTCP Basic Test............................................N/A\n");
228
229 test_control_return(3);
230 }
231 #endif
232
233