Asterisk - The Open Source Telephony Project  18.5.0
Enumerations | Functions | Variables
test_res_rtp.c File Reference

RTP/RTCP Unit Tests. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/data_buffer.h"
#include "asterisk/format_cache.h"
Include dependency graph for test_res_rtp.c:

Go to the source code of this file.

Enumerations

enum  test_type { TEST_TYPE_NONE = 0, TEST_TYPE_NACK, TEST_TYPE_REMB }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void ast_sched_context_destroy_wrapper (struct ast_sched_context *sched)
 
 AST_TEST_DEFINE (nack_no_packet_loss)
 
 AST_TEST_DEFINE (nack_nominal)
 
 AST_TEST_DEFINE (nack_overflow)
 
 AST_TEST_DEFINE (lost_packet_stats_nominal)
 
 AST_TEST_DEFINE (remb_nominal)
 
 AST_TEST_DEFINE (sr_rr_nominal)
 
 AST_TEST_DEFINE (fir_nominal)
 
static int load_module (void)
 
static int test_init_rtp_instances (struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
 
static void test_read_frames (struct ast_rtp_instance *instance, int num)
 
static void test_write_and_read_frames (struct ast_rtp_instance *instance1, struct ast_rtp_instance *instance2, int seqno, int num)
 
static void test_write_frames (struct ast_rtp_instance *instance, int seqno, int num)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "RTP/RTCP test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

RTP/RTCP Unit Tests.

Author
Ben Ford bford.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file test_res_rtp.c.

Enumeration Type Documentation

◆ test_type

enum test_type
Enumerator
TEST_TYPE_NONE 
TEST_TYPE_NACK 
TEST_TYPE_REMB 

Definition at line 40 of file test_res_rtp.c.

40  {
41  TEST_TYPE_NONE = 0, /* No special setup required */
42  TEST_TYPE_NACK, /* Enable NACK */
43  TEST_TYPE_REMB, /* Enable REMB */
44 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 550 of file test_res_rtp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 550 of file test_res_rtp.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 550 of file test_res_rtp.c.

◆ ast_sched_context_destroy_wrapper()

static void ast_sched_context_destroy_wrapper ( struct ast_sched_context sched)
static

Definition at line 46 of file test_res_rtp.c.

References ast_sched_context_destroy().

Referenced by AST_TEST_DEFINE().

47 {
48  if (sched) {
50  }
51 }
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269

◆ AST_TEST_DEFINE() [1/7]

AST_TEST_DEFINE ( nack_no_packet_loss  )

Definition at line 133 of file test_res_rtp.c.

References ast_log, ast_rtp_instance_destroy(), ast_rtp_instance_get_recv_buffer_count(), ast_rtp_instance_get_send_buffer_count(), ast_sched_context_create(), ast_sched_context_destroy_wrapper(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), LOG_ERROR, NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, test_init_rtp_instances(), TEST_TYPE_NACK, and test_write_and_read_frames().

134 {
138 
139  switch (cmd) {
140  case TEST_INIT:
141  info->name = "nack_no_packet_loss";
142  info->category = "/res/res_rtp/";
143  info->summary = "nack no packet loss unit test";
144  info->description =
145  "Tests sending packets with no packet loss and "
146  "validates that the send buffer stores sent packets "
147  "and the receive buffer is empty";
148  return AST_TEST_NOT_RUN;
149  case TEST_EXECUTE:
150  break;
151  }
152 
153  test_sched = ast_sched_context_create();
154 
155  if ((test_init_rtp_instances(&instance1, &instance2, test_sched, TEST_TYPE_NACK)) < 0) {
156  ast_log(LOG_ERROR, "Failed to initialize test!\n");
157  return AST_TEST_FAIL;
158  }
159 
160  test_write_and_read_frames(instance1, instance2, 1000, 10);
161 
162  ast_test_validate(test, ast_rtp_instance_get_send_buffer_count(instance1) == 10,
163  "Send buffer did not have the expected count of 10");
164 
165  ast_test_validate(test, ast_rtp_instance_get_recv_buffer_count(instance2) == 0,
166  "Receive buffer did not have the expected count of 0");
167 
168  return AST_TEST_PASS;
169 }
static int test_init_rtp_instances(struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
Definition: test_res_rtp.c:53
static void test_write_and_read_frames(struct ast_rtp_instance *instance1, struct ast_rtp_instance *instance2, int seqno, int num)
Definition: test_res_rtp.c:126
#define NULL
Definition: resample.c:96
static void ast_sched_context_destroy_wrapper(struct ast_sched_context *sched)
Definition: test_res_rtp.c:46
#define ast_log
Definition: astobj2.c:42
size_t ast_rtp_instance_get_send_buffer_count(struct ast_rtp_instance *instance)
Get the current size of the send buffer.
Definition: rtp_engine.c:3874
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
size_t ast_rtp_instance_get_recv_buffer_count(struct ast_rtp_instance *instance)
Get the current size of the receive buffer.
Definition: rtp_engine.c:3857
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458

◆ AST_TEST_DEFINE() [2/7]

AST_TEST_DEFINE ( nack_nominal  )

Definition at line 171 of file test_res_rtp.c.

References ast_log, ast_rtp_instance_destroy(), ast_rtp_instance_drop_packets(), ast_rtp_instance_get_recv_buffer_count(), ast_rtp_instance_get_recv_buffer_max(), ast_sched_context_create(), ast_sched_context_destroy_wrapper(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), LOG_ERROR, NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, test_init_rtp_instances(), test_read_frames(), TEST_TYPE_NACK, and test_write_and_read_frames().

172 {
176 
177  switch (cmd) {
178  case TEST_INIT:
179  info->name = "nack_nominal";
180  info->category = "/res/res_rtp/";
181  info->summary = "nack nominal unit test";
182  info->description =
183  "Tests sending packets with some packet loss and "
184  "validates that a NACK request is sent on reaching "
185  "the triggering amount of lost packets";
186  return AST_TEST_NOT_RUN;
187  case TEST_EXECUTE:
188  break;
189  }
190 
191  test_sched = ast_sched_context_create();
192 
193  if ((test_init_rtp_instances(&instance1, &instance2, test_sched, TEST_TYPE_NACK)) < 0) {
194  ast_log(LOG_ERROR, "Failed to initialize test!\n");
195  return AST_TEST_FAIL;
196  }
197 
198  /* Start normally */
199  test_write_and_read_frames(instance1, instance2, 1000, 10);
200 
201  /* Set the number of packets to drop when we send them next */
202  ast_rtp_instance_drop_packets(instance2, 10);
203  test_write_and_read_frames(instance1, instance2, 1010, 10);
204 
205  /* Send enough packets to reach the NACK trigger */
206  test_write_and_read_frames(instance1, instance2, 1020, ast_rtp_instance_get_recv_buffer_max(instance2) / 2);
207 
208  /* This needs to be read as RTCP */
209  test_read_frames(instance1, 1);
210 
211  /* We should have the missing packets to read now */
212  test_read_frames(instance2, 10);
213 
214  ast_test_validate(test, ast_rtp_instance_get_recv_buffer_count(instance2) == 0,
215  "Receive buffer did not have the expected count of 0");
216 
217  return AST_TEST_PASS;
218 }
static int test_init_rtp_instances(struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
Definition: test_res_rtp.c:53
static void test_write_and_read_frames(struct ast_rtp_instance *instance1, struct ast_rtp_instance *instance2, int seqno, int num)
Definition: test_res_rtp.c:126
static void test_read_frames(struct ast_rtp_instance *instance, int num)
Definition: test_res_rtp.c:113
#define NULL
Definition: resample.c:96
static void ast_sched_context_destroy_wrapper(struct ast_sched_context *sched)
Definition: test_res_rtp.c:46
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
size_t ast_rtp_instance_get_recv_buffer_count(struct ast_rtp_instance *instance)
Get the current size of the receive buffer.
Definition: rtp_engine.c:3857
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
void ast_rtp_instance_drop_packets(struct ast_rtp_instance *instance, int num)
Set the number of packets to drop on RTP read.
Definition: rtp_engine.c:3905
size_t ast_rtp_instance_get_recv_buffer_max(struct ast_rtp_instance *instance)
Get the maximum size of the receive buffer.
Definition: rtp_engine.c:3840

◆ AST_TEST_DEFINE() [3/7]

AST_TEST_DEFINE ( nack_overflow  )

Definition at line 220 of file test_res_rtp.c.

References ast_log, ast_rtp_instance_destroy(), ast_rtp_instance_get_recv_buffer_count(), ast_rtp_instance_get_recv_buffer_max(), ast_sched_context_create(), ast_sched_context_destroy_wrapper(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), LOG_ERROR, NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, test_init_rtp_instances(), TEST_TYPE_NACK, and test_write_and_read_frames().

221 {
225  int max_packets;
226 
227  switch (cmd) {
228  case TEST_INIT:
229  info->name = "nack_overflow";
230  info->category = "/res/res_rtp/";
231  info->summary = "nack overflow unit test";
232  info->description =
233  "Tests that when the buffer hits its capacity, we "
234  "queue all the packets we currently have stored";
235  return AST_TEST_NOT_RUN;
236  case TEST_EXECUTE:
237  break;
238  }
239 
240  test_sched = ast_sched_context_create();
241 
242  if ((test_init_rtp_instances(&instance1, &instance2, test_sched, TEST_TYPE_NACK)) < 0) {
243  ast_log(LOG_ERROR, "Failed to initialize test!\n");
244  return AST_TEST_FAIL;
245  }
246 
247  /* Start normally */
248  test_write_and_read_frames(instance1, instance2, 1000, 10);
249 
250  /* Send enough packets to fill the buffer */
251  max_packets = ast_rtp_instance_get_recv_buffer_max(instance2);
252  test_write_and_read_frames(instance1, instance2, 1020, max_packets);
253 
254  ast_test_validate(test, ast_rtp_instance_get_recv_buffer_count(instance2) == max_packets,
255  "Receive buffer did not have the expected count of max buffer size");
256 
257  /* Send the packet that will overflow the buffer */
258  test_write_and_read_frames(instance1, instance2, 1020 + max_packets, 1);
259 
260  ast_test_validate(test, ast_rtp_instance_get_recv_buffer_count(instance2) == 0,
261  "Receive buffer did not have the expected count of 0");
262 
263  return AST_TEST_PASS;
264 }
static int test_init_rtp_instances(struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
Definition: test_res_rtp.c:53
static void test_write_and_read_frames(struct ast_rtp_instance *instance1, struct ast_rtp_instance *instance2, int seqno, int num)
Definition: test_res_rtp.c:126
#define NULL
Definition: resample.c:96
static void ast_sched_context_destroy_wrapper(struct ast_sched_context *sched)
Definition: test_res_rtp.c:46
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
size_t ast_rtp_instance_get_recv_buffer_count(struct ast_rtp_instance *instance)
Get the current size of the receive buffer.
Definition: rtp_engine.c:3857
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
size_t ast_rtp_instance_get_recv_buffer_max(struct ast_rtp_instance *instance)
Get the maximum size of the receive buffer.
Definition: rtp_engine.c:3840

◆ AST_TEST_DEFINE() [4/7]

AST_TEST_DEFINE ( lost_packet_stats_nominal  )

Definition at line 266 of file test_res_rtp.c.

References ast_log, ast_rtp_instance_destroy(), ast_rtp_instance_get_stats(), ast_rtp_instance_queue_report(), AST_RTP_INSTANCE_STAT_ALL, ast_sched_context_create(), ast_sched_context_destroy_wrapper(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minrxploss, LOG_ERROR, NULL, RAII_VAR, ast_rtp_instance_stats::rxploss, TEST_EXECUTE, TEST_INIT, test_init_rtp_instances(), TEST_TYPE_NONE, test_write_and_read_frames(), and test_write_frames().

267 {
271  struct ast_rtp_instance_stats stats = { 0, };
273 
274  switch (cmd) {
275  case TEST_INIT:
276  info->name = "lost_packet_stats_nominal";
277  info->category = "/res/res_rtp/";
278  info->summary = "lost packet stats nominal unit test";
279  info->description =
280  "Tests that when some packets are lost, we calculate that "
281  "loss correctly when doing lost packet statistics";
282  return AST_TEST_NOT_RUN;
283  case TEST_EXECUTE:
284  break;
285  }
286 
287  test_sched = ast_sched_context_create();
288 
289  if ((test_init_rtp_instances(&instance1, &instance2, test_sched, TEST_TYPE_NONE)) < 0) {
290  ast_log(LOG_ERROR, "Failed to initialize test!\n");
291  return AST_TEST_FAIL;
292  }
293 
294  /* Start normally */
295  test_write_and_read_frames(instance1, instance2, 1000, 10);
296 
297  /* Send some more packets, but with a gap */
298  test_write_and_read_frames(instance1, instance2, 1015, 5);
299 
300  /* Send a RR to calculate lost packet statistics. We should be missing 5 packets */
302  test_write_frames(instance2, 1000, 1);
303 
304  /* Check RTCP stats to see if we got the expected packet loss count */
305  ast_rtp_instance_get_stats(instance2, &stats, stat);
306  ast_test_validate(test, stats.rxploss == 5 && stats.local_minrxploss == 5 &&
307  stats.local_maxrxploss == 5, "Condition of 5 lost packets was not met");
308 
309  /* Drop 3 before writing 5 more */
310  test_write_and_read_frames(instance1, instance2, 1023, 5);
311 
313  test_write_frames(instance2, 1001, 1);
314  ast_rtp_instance_get_stats(instance2, &stats, stat);
315 
316  /* Should now be missing 8 total packets with a change in min */
317  ast_test_validate(test, stats.rxploss == 8 && stats.local_minrxploss == 3 &&
318  stats.local_maxrxploss == 5);
319 
320  /* Write 5 more with no gaps */
321  test_write_and_read_frames(instance1, instance2, 1028, 5);
322 
324  test_write_frames(instance2, 1002, 1);
325  ast_rtp_instance_get_stats(instance2, &stats, stat);
326 
327  /* Should still only be missing 8 total packets */
328  ast_test_validate(test, stats.rxploss == 8 && stats.local_minrxploss == 3 &&
329  stats.local_maxrxploss == 5);
330 
331  /* Now drop 1, write another 5, drop 8, and then write 5 */
332  test_write_and_read_frames(instance1, instance2, 1034, 5);
333  test_write_and_read_frames(instance1, instance2, 1047, 5);
334 
336  test_write_frames(instance2, 1003, 1);
337  ast_rtp_instance_get_stats(instance2, &stats, stat);
338 
339  /* Now it should be missing 17 total packets, with a change in max */
340  ast_test_validate(test, stats.rxploss == 17 && stats.local_minrxploss == 3 &&
341  stats.local_maxrxploss == 9);
342 
343  return AST_TEST_PASS;
344 }
static int test_init_rtp_instances(struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
Definition: test_res_rtp.c:53
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2446
static void test_write_and_read_frames(struct ast_rtp_instance *instance1, struct ast_rtp_instance *instance2, int seqno, int num)
Definition: test_res_rtp.c:126
unsigned int rxploss
Definition: rtp_engine.h:394
static void test_write_frames(struct ast_rtp_instance *instance, int seqno, int num)
Definition: test_res_rtp.c:94
#define NULL
Definition: resample.c:96
static void ast_sched_context_destroy_wrapper(struct ast_sched_context *sched)
Definition: test_res_rtp.c:46
#define ast_log
Definition: astobj2.c:42
ast_rtp_instance_stat
Definition: rtp_engine.h:180
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
void ast_rtp_instance_queue_report(struct ast_rtp_instance *instance)
Sends a SR/RR report the next time RTP would be sent.
Definition: rtp_engine.c:3917

◆ AST_TEST_DEFINE() [5/7]

AST_TEST_DEFINE ( remb_nominal  )

Definition at line 346 of file test_res_rtp.c.

References AST_FRAME_RTCP, ast_frfree, ast_log, ast_rtp_instance_destroy(), ast_rtp_instance_read(), ast_rtp_instance_set_schedid(), ast_rtp_instance_write(), AST_RTP_RTCP_FMT_REMB, AST_RTP_RTCP_PSFB, ast_sched_context_create(), ast_sched_context_destroy_wrapper(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_rtp_rtcp_feedback_remb::br_exp, ast_rtp_rtcp_feedback_remb::br_mantissa, ast_rtp_rtcp_feedback::fmt, ast_frame::frametype, sip_to_pjsip::info(), LOG_ERROR, NULL, RAII_VAR, ast_rtp_rtcp_feedback::remb, TEST_EXECUTE, TEST_INIT, test_init_rtp_instances(), and TEST_TYPE_REMB.

347 {
351  RAII_VAR(struct ast_frame *, frame_in, NULL, ast_frfree);
352  /* Use the structure softmix_remb_collector uses to store information for REMB */
353  struct ast_rtp_rtcp_feedback feedback = {
355  .remb.br_exp = 0,
356  .remb.br_mantissa = 1000,
357  };
358  struct ast_frame frame_out = {
360  .subclass.integer = AST_RTP_RTCP_PSFB,
361  .data.ptr = &feedback,
362  .datalen = sizeof(feedback),
363  };
364  struct ast_rtp_rtcp_feedback *received_feedback;
365 
366  switch (cmd) {
367  case TEST_INIT:
368  info->name = "remb_nominal";
369  info->category = "/res/res_rtp/";
370  info->summary = "remb nominal unit test";
371  info->description =
372  "Tests sending and receiving a REMB packet";
373  return AST_TEST_NOT_RUN;
374  case TEST_EXECUTE:
375  break;
376  }
377 
378  test_sched = ast_sched_context_create();
379 
380  if ((test_init_rtp_instances(&instance1, &instance2, test_sched, TEST_TYPE_REMB)) < 0) {
381  ast_log(LOG_ERROR, "Failed to initialize test!\n");
382  return AST_TEST_FAIL;
383  }
384 
385  /* The schedid must be 0 or greater, so let's do that now */
386  ast_rtp_instance_set_schedid(instance1, 0);
387 
388  ast_rtp_instance_write(instance1, &frame_out);
389 
390  /* Verify the high level aspects of the frame */
391  frame_in = ast_rtp_instance_read(instance2, 0);
392  ast_test_validate(test, frame_in != NULL, "Did not receive a REMB frame");
393  ast_test_validate(test, frame_in->frametype == AST_FRAME_RTCP,
394  "REMB frame did not have the expected frametype");
395  ast_test_validate(test, frame_in->subclass.integer == AST_RTP_RTCP_PSFB,
396  "REMB frame did not have the expected subclass integer");
397 
398  /* Verify the actual REMB information itself */
399  received_feedback = frame_in->data.ptr;
400  ast_test_validate(test, received_feedback->fmt == AST_RTP_RTCP_FMT_REMB,
401  "REMB frame did not have the expected feedback format");
402  ast_test_validate(test, received_feedback->remb.br_exp == feedback.remb.br_exp,
403  "REMB received exponent did not match sent exponent");
404  ast_test_validate(test, received_feedback->remb.br_mantissa == feedback.remb.br_mantissa,
405  "REMB received mantissa did not match sent mantissa");
406 
407  return AST_TEST_PASS;
408 }
static int test_init_rtp_instances(struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
Definition: test_res_rtp.c:53
void ast_rtp_instance_set_schedid(struct ast_rtp_instance *instance, int id)
Set the schedid for RTCP.
Definition: rtp_engine.c:3891
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
An object that represents data received in a feedback report.
Definition: rtp_engine.h:358
unsigned int fmt
Definition: rtp_engine.h:359
struct ast_rtp_rtcp_feedback_remb remb
Definition: rtp_engine.h:361
#define NULL
Definition: resample.c:96
static void ast_sched_context_destroy_wrapper(struct ast_sched_context *sched)
Definition: test_res_rtp.c:46
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
#define ast_frfree(fr)
Data structure associated with a single frame of data.
#define AST_RTP_RTCP_PSFB
Definition: rtp_engine.h:299
enum ast_frame_type frametype
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578
#define AST_RTP_RTCP_FMT_REMB
Definition: rtp_engine.h:309

◆ AST_TEST_DEFINE() [6/7]

AST_TEST_DEFINE ( sr_rr_nominal  )

Definition at line 410 of file test_res_rtp.c.

References AST_FRAME_RTCP, ast_frfree, ast_log, ast_rtp_instance_destroy(), ast_rtp_instance_get_sdes_received(), ast_rtp_instance_queue_report(), ast_rtp_instance_read(), AST_RTP_RTCP_RR, AST_RTP_RTCP_SR, ast_sched_context_create(), ast_sched_context_destroy_wrapper(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), LOG_ERROR, NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, test_init_rtp_instances(), TEST_TYPE_NONE, test_write_and_read_frames(), and test_write_frames().

411 {
415  RAII_VAR(struct ast_frame *, frame_in, NULL, ast_frfree);
416 
417  switch (cmd) {
418  case TEST_INIT:
419  info->name = "sr_rr_nominal";
420  info->category = "/res/res_rtp/";
421  info->summary = "SR/RR nominal unit test";
422  info->description =
423  "Tests sending SR/RR and receiving it; includes SDES";
424  return AST_TEST_NOT_RUN;
425  case TEST_EXECUTE:
426  break;
427  }
428 
429  test_sched = ast_sched_context_create();
430 
431  if ((test_init_rtp_instances(&instance1, &instance2, test_sched, TEST_TYPE_NONE)) < 0) {
432  ast_log(LOG_ERROR, "Failed to initialize test!\n");
433  return AST_TEST_FAIL;
434  }
435 
436  test_write_and_read_frames(instance1, instance2, 1000, 10);
437 
438  /*
439  * Set the send_report flag so we send a sender report instead of normal RTP. We
440  * also need to ensure that SDES processed.
441  */
443  test_write_frames(instance1, 1010, 1);
444 
445  frame_in = ast_rtp_instance_read(instance2, 0);
446  ast_test_validate(test, frame_in->frametype == AST_FRAME_RTCP,
447  "Sender report frame did not have the expected frametype");
448  ast_test_validate(test, frame_in->subclass.integer == AST_RTP_RTCP_SR,
449  "Sender report frame did not have the expected subclass integer");
450  ast_test_validate(test, ast_rtp_instance_get_sdes_received(instance2) == 1,
451  "SDES was never processed for sender report");
452 
453  ast_frfree(frame_in);
454 
455  /* Set the send_report flag so we send a receiver report instead of normal RTP */
457  test_write_frames(instance1, 1010, 1);
458 
459  frame_in = ast_rtp_instance_read(instance2, 0);
460  ast_test_validate(test, frame_in->frametype == AST_FRAME_RTCP,
461  "Receiver report frame did not have the expected frametype");
462  ast_test_validate(test, frame_in->subclass.integer == AST_RTP_RTCP_RR,
463  "Receiver report frame did not have the expected subclass integer");
464 
465  return AST_TEST_PASS;
466 }
static int test_init_rtp_instances(struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
Definition: test_res_rtp.c:53
static void test_write_and_read_frames(struct ast_rtp_instance *instance1, struct ast_rtp_instance *instance2, int seqno, int num)
Definition: test_res_rtp.c:126
static void test_write_frames(struct ast_rtp_instance *instance, int seqno, int num)
Definition: test_res_rtp.c:94
#define NULL
Definition: resample.c:96
static void ast_sched_context_destroy_wrapper(struct ast_sched_context *sched)
Definition: test_res_rtp.c:46
int ast_rtp_instance_get_sdes_received(struct ast_rtp_instance *instance)
Get the value of sdes_received on the test engine.
Definition: rtp_engine.c:3929
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
#define AST_RTP_RTCP_RR
Definition: rtp_engine.h:295
#define AST_RTP_RTCP_SR
Definition: rtp_engine.h:293
#define ast_frfree(fr)
Data structure associated with a single frame of data.
void ast_rtp_instance_queue_report(struct ast_rtp_instance *instance)
Sends a SR/RR report the next time RTP would be sent.
Definition: rtp_engine.c:3917
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578

◆ AST_TEST_DEFINE() [7/7]

AST_TEST_DEFINE ( fir_nominal  )

Definition at line 468 of file test_res_rtp.c.

References AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, ast_frfree, ast_log, ast_rtp_instance_destroy(), ast_rtp_instance_read(), ast_rtp_instance_set_schedid(), ast_rtp_instance_write(), ast_sched_context_create(), ast_sched_context_destroy_wrapper(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_frame::frametype, sip_to_pjsip::info(), LOG_ERROR, NULL, RAII_VAR, TEST_EXECUTE, TEST_INIT, test_init_rtp_instances(), TEST_TYPE_NONE, and test_write_and_read_frames().

469 {
473  RAII_VAR(struct ast_frame *, frame_in, NULL, ast_frfree);
474  struct ast_frame frame_out = {
476  .subclass.integer = AST_CONTROL_VIDUPDATE,
477  };
478 
479  switch (cmd) {
480  case TEST_INIT:
481  info->name = "fir_nominal";
482  info->category = "/res/res_rtp/";
483  info->summary = "fir nominal unit test";
484  info->description =
485  "Tests sending and receiving a FIR packet";
486  return AST_TEST_NOT_RUN;
487  case TEST_EXECUTE:
488  break;
489  }
490 
491  test_sched = ast_sched_context_create();
492 
493  if ((test_init_rtp_instances(&instance1, &instance2, test_sched, TEST_TYPE_NONE)) < 0) {
494  ast_log(LOG_ERROR, "Failed to initialize test!\n");
495  return AST_TEST_FAIL;
496  }
497 
498  /* Send some packets to learn SSRC */
499  test_write_and_read_frames(instance2, instance1, 1000, 10);
500 
501  /* The schedid must be 0 or greater, so let's do that now */
502  ast_rtp_instance_set_schedid(instance1, 0);
503 
504  /*
505  * This will not directly write a frame out, but cause Asterisk to see it as a FIR
506  * request, which will then trigger rtp_write_rtcp_fir, which will send out the
507  * appropriate packet.
508  */
509  ast_rtp_instance_write(instance1, &frame_out);
510 
511  /*
512  * We only receive one frame, the FIR request. It won't have a subclass integer of
513  * 206 (PSFB) because ast_rtcp_interpret sets it to 18 (AST_CONTROL_VIDUPDATE), so
514  * check for that.
515  */
516  frame_in = ast_rtp_instance_read(instance2, 0);
517  ast_test_validate(test, frame_in != NULL, "Did not receive a FIR frame");
518  ast_test_validate(test, frame_in->frametype == AST_FRAME_CONTROL,
519  "FIR frame did not have the expected frametype");
520  ast_test_validate(test, frame_in->subclass.integer == AST_CONTROL_VIDUPDATE,
521  "FIR frame did not have the expected subclass integer");
522 
523  return AST_TEST_PASS;
524 }
static int test_init_rtp_instances(struct ast_rtp_instance **instance1, struct ast_rtp_instance **instance2, struct ast_sched_context *test_sched, enum test_type type)
Definition: test_res_rtp.c:53
void ast_rtp_instance_set_schedid(struct ast_rtp_instance *instance, int id)
Set the schedid for RTCP.
Definition: rtp_engine.c:3891
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
static void test_write_and_read_frames(struct ast_rtp_instance *instance1, struct ast_rtp_instance *instance2, int seqno, int num)
Definition: test_res_rtp.c:126
#define NULL
Definition: resample.c:96
static void ast_sched_context_destroy_wrapper(struct ast_sched_context *sched)
Definition: test_res_rtp.c:46
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
#define ast_frfree(fr)
Data structure associated with a single frame of data.
enum ast_frame_type frametype
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578

◆ load_module()

static int load_module ( void  )
static

Definition at line 538 of file test_res_rtp.c.

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

539 {
540  AST_TEST_REGISTER(nack_no_packet_loss);
541  AST_TEST_REGISTER(nack_nominal);
542  AST_TEST_REGISTER(nack_overflow);
543  AST_TEST_REGISTER(lost_packet_stats_nominal);
544  AST_TEST_REGISTER(remb_nominal);
545  AST_TEST_REGISTER(sr_rr_nominal);
546  AST_TEST_REGISTER(fir_nominal);
548 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

◆ test_init_rtp_instances()

static int test_init_rtp_instances ( struct ast_rtp_instance **  instance1,
struct ast_rtp_instance **  instance2,
struct ast_sched_context test_sched,
enum test_type  type 
)
static

Definition at line 53 of file test_res_rtp.c.

References ast_rtp_instance_activate(), ast_rtp_instance_get_local_address(), ast_rtp_instance_new(), ast_rtp_instance_reset_test_engine(), AST_RTP_INSTANCE_RTCP_MUX, ast_rtp_instance_set_prop(), ast_rtp_instance_set_remote_address, AST_RTP_PROPERTY_REMB, AST_RTP_PROPERTY_RETRANS_RECV, AST_RTP_PROPERTY_RETRANS_SEND, AST_RTP_PROPERTY_RTCP, ast_sockaddr_parse(), NULL, TEST_TYPE_NACK, and TEST_TYPE_REMB.

Referenced by AST_TEST_DEFINE().

56 {
57  struct ast_sockaddr addr;
58 
59  ast_sockaddr_parse(&addr, "127.0.0.1", 0);
60 
61  *instance1 = ast_rtp_instance_new("asterisk", test_sched, &addr, NULL);
62  *instance2 = ast_rtp_instance_new("asterisk", test_sched, &addr, NULL);
63  if (!instance1 || !instance2) {
64  return -1;
65  }
66 
69 
70  if (type == TEST_TYPE_NACK) {
75  } else if (type == TEST_TYPE_REMB) {
78  }
79 
80  ast_rtp_instance_get_local_address(*instance1, &addr);
81  ast_rtp_instance_set_remote_address(*instance2, &addr);
82 
83  ast_rtp_instance_get_local_address(*instance2, &addr);
84  ast_rtp_instance_set_remote_address(*instance1, &addr);
85 
87 
88  ast_rtp_instance_activate(*instance1);
89  ast_rtp_instance_activate(*instance2);
90 
91  return 0;
92 }
static const char type[]
Definition: chan_ooh323.c:109
int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance...
Definition: rtp_engine.c:2647
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1080
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:465
void ast_rtp_instance_reset_test_engine(struct ast_rtp_instance *instance)
Resets all the fields to default values for the test engine.
Definition: rtp_engine.c:3941

◆ test_read_frames()

static void test_read_frames ( struct ast_rtp_instance instance,
int  num 
)
static

Definition at line 113 of file test_res_rtp.c.

References ast_frfree, and ast_rtp_instance_read().

Referenced by AST_TEST_DEFINE(), and test_write_and_read_frames().

114 {
115  struct ast_frame *frame_in;
116  int index;
117 
118  for (index = 0; index < num; index++) {
119  frame_in = ast_rtp_instance_read(instance, 0);
120  if (frame_in) {
121  ast_frfree(frame_in);
122  }
123  }
124 }
#define ast_frfree(fr)
Data structure associated with a single frame of data.
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578

◆ test_write_and_read_frames()

static void test_write_and_read_frames ( struct ast_rtp_instance instance1,
struct ast_rtp_instance instance2,
int  seqno,
int  num 
)
static

Definition at line 126 of file test_res_rtp.c.

References test_read_frames(), and test_write_frames().

Referenced by AST_TEST_DEFINE().

128 {
129  test_write_frames(instance1, seqno, num);
130  test_read_frames(instance2, num);
131 }
static void test_write_frames(struct ast_rtp_instance *instance, int seqno, int num)
Definition: test_res_rtp.c:94
static void test_read_frames(struct ast_rtp_instance *instance, int num)
Definition: test_res_rtp.c:113

◆ test_write_frames()

static void test_write_frames ( struct ast_rtp_instance instance,
int  seqno,
int  num 
)
static

Definition at line 94 of file test_res_rtp.c.

References ast_format_ulaw, AST_FRAME_VOICE, AST_FRFLAG_HAS_SEQUENCE_NUMBER, ast_rtp_instance_write(), ast_set_flag, ast_frame::data, ast_frame::frametype, and ast_frame::seqno.

Referenced by AST_TEST_DEFINE(), and test_write_and_read_frames().

95 {
96  char data[320] = "";
97  struct ast_frame frame_out = {
99  .subclass.format = ast_format_ulaw,
100  .data.ptr = data,
101  .datalen = 160,
102  };
103  int index;
104 
106 
107  for (index = 0; index < num; index++) {
108  frame_out.seqno = seqno + index;
109  ast_rtp_instance_write(instance, &frame_out);
110  }
111 }
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 526 of file test_res_rtp.c.

References AST_TEST_UNREGISTER.

527 {
528  AST_TEST_UNREGISTER(nack_no_packet_loss);
529  AST_TEST_UNREGISTER(nack_nominal);
530  AST_TEST_UNREGISTER(nack_overflow);
531  AST_TEST_UNREGISTER(lost_packet_stats_nominal);
532  AST_TEST_UNREGISTER(remb_nominal);
533  AST_TEST_UNREGISTER(sr_rr_nominal);
534  AST_TEST_UNREGISTER(fir_nominal);
535  return 0;
536 }
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "RTP/RTCP test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 550 of file test_res_rtp.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 550 of file test_res_rtp.c.