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 CNAME                      "AzureRTOS@microsoft.com"
22 
23 /* Define the ThreadX object control blocks...  */
24 
25 static TX_THREAD                   ntest_0;
26 static TX_THREAD                   ntest_1;
27 
28 static NX_PACKET_POOL              pool_0;
29 static NX_IP                       ip_0;
30 static NX_IP                       ip_1;
31 static NX_UDP_SOCKET               rtp_client_socket;
32 
33 /* Define rtp sender control block.  */
34 static NX_RTP_SENDER               rtp_0;
35 static NX_RTP_SESSION              rtp_session_0;
36 
37 /* Define the counters used in the test application...  */
38 static TX_SEMAPHORE            semaphore_test_done;
39 
40 /* Define RTCP packet for testing.
41 --receiver report--
42    version: RFC 1899 Version (2)
43    padding: False
44    reception report count: 1
45    packet type: receiver report (201)
46    length: 7
47    sender ssrc: 1052681868
48    source 1:
49        identifier: 11478
50        fraction lost: 255
51        cumulative number of packets lost: -1
52        extended highest sequence number received: 94974
53        interarrival jitter: 444
54        last SR timestamp: 0
55        delay since last SR timestamp: 0
56 --source description--
57    version: RFC 1899 Version (2)
58    padding: False
59    source count: 1
60    packet type: source description (202)
61    length: 5
62    chunk 1:
63        indentifier: 1052681868
64        sdes item:
65             type: CNAME (1)
66             length:13
67             text: cn-test-cname
68             type: END (0)
69 */
70 static UCHAR test_rtcp_packet_data[]={
71 0x81, 0xc9, 0x00, 0x07, 0x3e, 0xbe, 0xa6, 0x8c, 0x00, 0x00, 0x2c, 0xd6, 0xff, 0xff, 0xff, 0xff,
72 0x00, 0x01, 0x72, 0xfe, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73,
74 0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00};
75 
76 static UCHAR test_rtp_receiver_cname[] = "cn-test-cname";
77 
78 /* Define thread prototypes.  */
79 
80 static void ntest_0_entry(ULONG thread_input);
81 static void ntest_1_entry(ULONG thread_input);
82 static UINT test_rtcp_receiver_report_callback(NX_RTP_SESSION *session, NX_RTCP_RECEIVER_REPORT *report);
83 static UINT test_rtcp_sdes_callback(NX_RTCP_SDES_INFO *sdes_info);
84 extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
85 extern void test_control_return(UINT status);
86 
87 #ifdef CTEST
test_application_define(void * first_unused_memory)88 VOID test_application_define(void *first_unused_memory)
89 #else
90 void    netx_rtcp_packet_process_test_application_define(void *first_unused_memory)
91 #endif
92 {
93 
94 CHAR       *pointer;
95 UINT        status;
96 
97     /* Print out test information banner.  */
98     printf("NetX Test:   RTCP Packet Pocess Test............................................");
99 
100     /* Setup the working pointer.  */
101     pointer =  (CHAR *) first_unused_memory;
102 
103     /* Create the server thread.  */
104     tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
105                      pointer, DEMO_STACK_SIZE,
106                      3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
107 
108     pointer = pointer + DEMO_STACK_SIZE;
109 
110     /* Create the client thread.  */
111     tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
112                      pointer, DEMO_STACK_SIZE,
113                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
114 
115     pointer = pointer + DEMO_STACK_SIZE;
116 
117     /* Initialize the NetX system.  */
118     nx_system_initialize();
119 
120     /* Create a packet pool.  */
121     status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE);
122     pointer = pointer + PACKET_POOL_SIZE;
123     CHECK_STATUS(0, status);
124 
125     /* Create server IP instance.  */
126     status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
127                           pointer, 2048, 1);
128     pointer = pointer + 2048;
129     CHECK_STATUS(0, status);
130 
131     /* Create client IP instance.  */
132     status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
133                           pointer, 2048, 1);
134     pointer = pointer + 2048;
135     CHECK_STATUS(0, status);
136 
137     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
138     status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
139     pointer = pointer + 1024;
140     CHECK_STATUS(0, status);
141 
142     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
143     status = nx_arp_enable(&ip_1, (void *) pointer, 1024);
144     pointer = pointer + 1024;
145     CHECK_STATUS(0, status);
146 
147     /* Enable UDP processing for both IP instances.  */
148     status = nx_udp_enable(&ip_0);
149     CHECK_STATUS(0, status);
150     status = nx_udp_enable(&ip_1);
151     CHECK_STATUS(0, status);
152 
153     tx_semaphore_create(&semaphore_test_done, "semaphore test done", 0);
154 }
155 
156 /* Define server threads.  */
ntest_0_entry(ULONG thread_input)157 static void    ntest_0_entry(ULONG thread_input)
158 {
159 UINT        status;
160 NXD_ADDRESS client_ip_address;
161 
162     /* Create RTP sender.  */
163     status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1);
164     CHECK_STATUS(0, status);
165     nx_rtp_sender_rtcp_receiver_report_callback_set(&rtp_0, test_rtcp_receiver_report_callback);
166     nx_rtp_sender_rtcp_sdes_callback_set(&rtp_0, test_rtcp_sdes_callback);
167 
168     /* Setup rtp sender session.  */
169     client_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
170     client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS;
171     status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE_VIDEO,
172                                           0, &client_ip_address,
173                                           RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT);
174 
175     /* Set session ssrc value the same as the source identifier in test_rtcp_packet_data packet.  */
176     rtp_session_0.nx_rtp_session_ssrc = 11478;
177 
178     CHECK_STATUS(0, status);
179 
180     status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE);
181     CHECK_STATUS(0, status);
182 
183     status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE);
184     CHECK_STATUS(0, status);
185 
186     status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE);
187     CHECK_STATUS(0, status);
188 
189     /* Return the test result.  */
190     printf("SUCCESS!\n");
191     test_control_return(0);
192 }
193 
194 /* Define the client threads.  */
ntest_1_entry(ULONG thread_input)195 static void    ntest_1_entry(ULONG thread_input)
196 {
197 NX_PACKET *send_packet;
198 UINT       status;
199 
200     /* Create the rtp client socket.  */
201     status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
202     CHECK_STATUS(0, status);
203 
204     status =  nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTCP_PORT, NX_IP_PERIODIC_RATE);
205     CHECK_STATUS(0, status);
206 
207     status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE);
208     CHECK_STATUS(0, status);
209 
210     status = nx_packet_data_append(send_packet, test_rtcp_packet_data, sizeof(test_rtcp_packet_data), &pool_0,  NX_IP_PERIODIC_RATE);
211     CHECK_STATUS(0, status);
212 
213     status = nx_udp_socket_send(&rtp_client_socket, send_packet, RTP_SERVER_ADDRESS, rtp_0.nx_rtp_sender_rtcp_port);
214     CHECK_STATUS(0, status);
215 
216     /* Set rtcp receiver report callback to NULL. */
217     status = nx_rtp_sender_rtcp_receiver_report_callback_set(&rtp_0, NX_NULL);
218     CHECK_STATUS(0, status);
219 
220     /* Set rtcp sdes callback to NULL. */
221     status = nx_rtp_sender_rtcp_sdes_callback_set(&rtp_0, NX_NULL);
222     CHECK_STATUS(0, status);
223 
224     status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE);
225     CHECK_STATUS(0, status);
226 
227     status = nx_packet_data_append(send_packet, test_rtcp_packet_data, sizeof(test_rtcp_packet_data), &pool_0,  NX_IP_PERIODIC_RATE);
228     CHECK_STATUS(0, status);
229 
230     status = nx_udp_socket_send(&rtp_client_socket, send_packet, RTP_SERVER_ADDRESS, rtp_0.nx_rtp_sender_rtcp_port);
231     CHECK_STATUS(0, status);
232 
233     tx_semaphore_put(&semaphore_test_done);
234 }
235 
test_rtcp_receiver_report_callback(NX_RTP_SESSION * session,NX_RTCP_RECEIVER_REPORT * report)236 static UINT test_rtcp_receiver_report_callback(NX_RTP_SESSION *session, NX_RTCP_RECEIVER_REPORT *report)
237 {
238     if((report->receiver_ssrc == 1052681868) &&
239        (report->fraction_loss == 255) &&
240        (report->packet_loss == -1) &&
241        (report->extended_max = 94974) &&
242        (report->jitter == 444) &&
243        (report->last_sr == 0) &&
244        (report->delay == 0))
245     {
246         tx_semaphore_put(&semaphore_test_done);
247     }
248 
249     return(NX_SUCCESS);
250 }
251 
test_rtcp_sdes_callback(NX_RTCP_SDES_INFO * sdes_info)252 static UINT test_rtcp_sdes_callback(NX_RTCP_SDES_INFO *sdes_info)
253 {
254     if((sdes_info->ssrc == 1052681868) &&
255        (strncmp(sdes_info->cname, test_rtp_receiver_cname, sizeof(test_rtp_receiver_cname) - 1) == 0) &&
256        (sdes_info->cname_length == sizeof(test_rtp_receiver_cname) - 1))
257     {
258         tx_semaphore_put(&semaphore_test_done);
259     }
260 
261     return NX_SUCCESS;
262 }
263 
264 #else
265 
266 #ifdef CTEST
test_application_define(void * first_unused_memory)267 VOID test_application_define(void *first_unused_memory)
268 #else
269 void    netx_rtcp_packet_process_test_application_define(void *first_unused_memory)
270 #endif
271 {
272 
273     /* Print out test information banner.  */
274     printf("NetX Test:   RTCP Packet Process Test............................................N/A\n");
275 
276     test_control_return(3);
277 }
278 #endif
279 
280