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