Asterisk - The Open Source Telephony Project  18.5.0
Functions
sip/dialplan_functions.c File Reference

sip channel dialplan functions and unit tests More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/channel.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/pbx.h"
#include "asterisk/acl.h"
#include "include/sip.h"
#include "include/globals.h"
#include "include/dialog.h"
#include "include/dialplan_functions.h"
#include "include/sip_utils.h"
Include dependency graph for sip/dialplan_functions.c:

Go to the source code of this file.

Functions

 AST_TEST_DEFINE (test_sip_rtpqos_1)
 
int sip_acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
 Channel read dialplan function for SIP. More...
 
void sip_dialplan_function_register_tests (void)
 SIP test registration. More...
 
void sip_dialplan_function_unregister_tests (void)
 SIP test registration. More...
 
static int test_sip_rtpqos_1_destroy (struct ast_rtp_instance *instance)
 
static int test_sip_rtpqos_1_get_stat (struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
 
static int test_sip_rtpqos_1_new (struct ast_rtp_instance *instance, struct ast_sched_context *sched, struct ast_sockaddr *addr, void *data)
 
static struct ast_frametest_sip_rtpqos_1_read (struct ast_rtp_instance *instance, int rtcp)
 
static int test_sip_rtpqos_1_write (struct ast_rtp_instance *instance, struct ast_frame *frame)
 

Detailed Description

sip channel dialplan functions and unit tests

Definition in file sip/dialplan_functions.c.

Function Documentation

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( test_sip_rtpqos_1  )

Definition at line 359 of file sip/dialplan_functions.c.

References ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unref, ast_dummy_channel_alloc, ast_free, ast_rtp_engine_register, ast_rtp_engine_unregister(), ast_rtp_instance_new(), ast_rtp_instance_set_remote_address, ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_substitute_variables(), ast_strlen_zero, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, bindaddr, dialog_ref, dialog_unlink_all(), dialog_unref, done, sip_to_pjsip::info(), ast_rtp_instance_stats::local_maxjitter, ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevrxploss, ast_rtp_instance_stats::maxrtt, ast_rtp_instance_stats::minrtt, name, ast_rtp_engine::name, ast_rtp_instance_stats::normdevrtt, NULL, sip_pvt::owner, ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, ast_rtp_instance_stats::remote_stdevrxploss, sip_pvt::rtp, ast_rtp_instance_stats::rtt, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, sip_alloc, SIP_NOTIFY, sip_tech, ast_rtp_instance_stats::stdevrtt, TEST_EXECUTE, TEST_INIT, test_sip_rtpqos_1_destroy(), test_sip_rtpqos_1_get_stat(), test_sip_rtpqos_1_new(), test_sip_rtpqos_1_read(), test_sip_rtpqos_1_write(), ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, ast_rtp_instance_stats::txploss, and type.

360 {
361  int i, res = AST_TEST_PASS;
362  static struct ast_rtp_engine test_engine = {
363  .name = "test",
364  .new = test_sip_rtpqos_1_new,
365  .destroy = test_sip_rtpqos_1_destroy,
366  .read = test_sip_rtpqos_1_read,
367  .write = test_sip_rtpqos_1_write,
368  .get_stat = test_sip_rtpqos_1_get_stat,
369  };
370  struct ast_sockaddr sa = { {0, } };
371  struct ast_rtp_instance_stats mine = { 0, };
372  struct sip_pvt *p = NULL;
373  struct ast_channel *chan = NULL;
374  struct ast_str *varstr = NULL, *buffer = NULL;
375  struct {
376  const char *name;
377  enum { INT, DBL } type;
378  union {
379  unsigned int *i4;
380  double *d8;
381  };
382  } lookup[] = {
383  { "txcount", INT, { .i4 = &mine.txcount, }, },
384  { "rxcount", INT, { .i4 = &mine.rxcount, }, },
385  { "txjitter", DBL, { .d8 = &mine.txjitter, }, },
386  { "rxjitter", DBL, { .d8 = &mine.rxjitter, }, },
387  { "remote_maxjitter", DBL, { .d8 = &mine.remote_maxjitter, }, },
388  { "remote_minjitter", DBL, { .d8 = &mine.remote_minjitter, }, },
389  { "remote_normdevjitter", DBL, { .d8 = &mine.remote_normdevjitter, }, },
390  { "remote_stdevjitter", DBL, { .d8 = &mine.remote_stdevjitter, }, },
391  { "local_maxjitter", DBL, { .d8 = &mine.local_maxjitter, }, },
392  { "local_minjitter", DBL, { .d8 = &mine.local_minjitter, }, },
393  { "local_normdevjitter", DBL, { .d8 = &mine.local_normdevjitter, }, },
394  { "local_stdevjitter", DBL, { .d8 = &mine.local_stdevjitter, }, },
395  { "txploss", INT, { .i4 = &mine.txploss, }, },
396  { "rxploss", INT, { .i4 = &mine.rxploss, }, },
397  { "remote_maxrxploss", DBL, { .d8 = &mine.remote_maxrxploss, }, },
398  { "remote_minrxploss", DBL, { .d8 = &mine.remote_minrxploss, }, },
399  { "remote_normdevrxploss", DBL, { .d8 = &mine.remote_normdevrxploss, }, },
400  { "remote_stdevrxploss", DBL, { .d8 = &mine.remote_stdevrxploss, }, },
401  { "local_maxrxploss", DBL, { .d8 = &mine.local_maxrxploss, }, },
402  { "local_minrxploss", DBL, { .d8 = &mine.local_minrxploss, }, },
403  { "local_normdevrxploss", DBL, { .d8 = &mine.local_normdevrxploss, }, },
404  { "local_stdevrxploss", DBL, { .d8 = &mine.local_stdevrxploss, }, },
405  { "rtt", DBL, { .d8 = &mine.rtt, }, },
406  { "maxrtt", DBL, { .d8 = &mine.maxrtt, }, },
407  { "minrtt", DBL, { .d8 = &mine.minrtt, }, },
408  { "normdevrtt", DBL, { .d8 = &mine.normdevrtt, }, },
409  { "stdevrtt", DBL, { .d8 = &mine.stdevrtt, }, },
410  { "local_ssrc", INT, { .i4 = &mine.local_ssrc, }, },
411  { "remote_ssrc", INT, { .i4 = &mine.remote_ssrc, }, },
412  { NULL, },
413  };
414 
415  switch (cmd) {
416  case TEST_INIT:
417  info->name = "test_sip_rtpqos";
418  info->category = "/channels/chan_sip/";
419  info->summary = "Test retrieval of SIP RTP QOS stats";
420  info->description =
421  "Verify values in the RTP instance structure can be accessed through the dialplan.";
422  return AST_TEST_NOT_RUN;
423  case TEST_EXECUTE:
424  break;
425  }
426 
427  ast_rtp_engine_register(&test_engine);
428  /* Have to associate this with a SIP pvt and an ast_channel */
429  if (!(p = sip_alloc(0, NULL, 0, SIP_NOTIFY, NULL, 0))) {
430  res = AST_TEST_NOT_RUN;
431  goto done;
432  }
433 
434  if (!(p->rtp = ast_rtp_instance_new("test", sched, &bindaddr, &mine))) {
435  res = AST_TEST_NOT_RUN;
436  goto done;
437  }
439  if (!(chan = ast_dummy_channel_alloc())) {
440  res = AST_TEST_NOT_RUN;
441  goto done;
442  }
444  ast_channel_tech_pvt_set(chan, dialog_ref(p, "Give the owner channel a reference to the dialog"));
445  p->owner = chan;
446 
447  varstr = ast_str_create(16);
448  buffer = ast_str_create(16);
449  if (!varstr || !buffer) {
450  res = AST_TEST_NOT_RUN;
451  goto done;
452  }
453 
454  /* Populate "mine" with values, then retrieve them with the CHANNEL dialplan function */
455  for (i = 0; !ast_strlen_zero(lookup[i].name); i++) {
456  ast_str_set(&varstr, 0, "${CHANNEL(rtpqos,audio,%s)}", lookup[i].name);
457  if (lookup[i].type == INT) {
458  int j;
459  char cmpstr[256];
460  for (j = 1; j < 25; j++) {
461  *lookup[i].i4 = j;
462  ast_str_substitute_variables(&buffer, 0, chan, ast_str_buffer(varstr));
463  snprintf(cmpstr, sizeof(cmpstr), "%d", j);
464  if (strcmp(cmpstr, ast_str_buffer(buffer))) {
465  res = AST_TEST_FAIL;
466  ast_test_status_update(test, "%s != %s != %s\n", ast_str_buffer(varstr), cmpstr, ast_str_buffer(buffer));
467  break;
468  }
469  }
470  } else {
471  double j, cmpdbl = 0.0;
472  for (j = 1.0; j < 10.0; j += 0.3) {
473  *lookup[i].d8 = j;
474  ast_str_substitute_variables(&buffer, 0, chan, ast_str_buffer(varstr));
475  if (sscanf(ast_str_buffer(buffer), "%lf", &cmpdbl) != 1 || fabs(j - cmpdbl) > .05) {
476  res = AST_TEST_FAIL;
477  ast_test_status_update(test, "%s != %f != %s\n", ast_str_buffer(varstr), j, ast_str_buffer(buffer));
478  break;
479  }
480  }
481  }
482  }
483 
484 done:
485  ast_free(varstr);
486  ast_free(buffer);
487 
488  /* This unlink and unref will take care of destroying the channel, RTP instance, and SIP pvt */
489  if (p) {
491  dialog_unref(p, "Destroy test object");
492  }
493  if (chan) {
494  ast_channel_unref(chan);
495  }
496  ast_rtp_engine_unregister(&test_engine);
497  return res;
498 }
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
#define ast_rtp_engine_register(engine)
Definition: rtp_engine.h:794
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
unsigned int txcount
Definition: rtp_engine.h:368
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Definition: sched.c:76
unsigned int rxploss
Definition: rtp_engine.h:394
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
int done
Definition: test_amihooks.c:48
static struct ast_frame * test_sip_rtpqos_1_read(struct ast_rtp_instance *instance, int rtcp)
void dialog_unlink_all(struct sip_pvt *dialog)
Unlink a dialog from the dialogs container, as well as any other places that it may be currently stor...
Definition: chan_sip.c:3367
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
Unregister an RTP engine.
Definition: rtp_engine.c:364
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static int test_sip_rtpqos_1_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
unsigned int rxcount
Definition: rtp_engine.h:370
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
unsigned int local_ssrc
Definition: rtp_engine.h:422
#define dialog_unref(dialog, tag)
Definition: dialog.h:33
#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
def info(msg)
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static const char name[]
Definition: cdr_mysql.c:74
unsigned int txploss
Definition: rtp_engine.h:392
#define ast_free(a)
Definition: astmm.h:182
struct ast_channel * owner
Definition: sip.h:1138
#define dialog_ref(dialog, tag)
when we create or delete references, make sure to use these functions so we keep track of the refcoun...
Definition: dialog.h:32
const char * name
Definition: rtp_engine.h:616
struct ast_rtp_instance * rtp
Definition: sip.h:1174
static int test_sip_rtpqos_1_destroy(struct ast_rtp_instance *instance)
static int test_sip_rtpqos_1_new(struct ast_rtp_instance *instance, struct ast_sched_context *sched, struct ast_sockaddr *addr, void *data)
static int test_sip_rtpqos_1_get_stat(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
struct ast_channel_tech sip_tech
Definition of this channel for PBX channel registration.
Definition: chan_sip.c:1573
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_channel_tech_pvt_set(struct ast_channel *chan, void *value)
struct ast_sockaddr bindaddr
Definition: chan_ooh323.c:353
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
unsigned int remote_ssrc
Definition: rtp_engine.h:424

◆ sip_acf_channel_read()

int sip_acf_channel_read ( struct ast_channel chan,
const char *  funcname,
char *  preparse,
char *  buf,
size_t  buflen 
)

Channel read dialplan function for SIP.

Definition at line 127 of file sip/dialplan_functions.c.

References args, AST_APP_ARG, ast_channel_tech(), ast_channel_tech_pvt(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log, AST_MAX_USER_FIELD, ast_ouraddrfor(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_quality(), ast_rtp_instance_get_remote_address, ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, AST_TRANSPORT_TLS, sip_pvt::from, sip_pvt::initreq, IS_SIP_TECH, ast_rtp_instance_stats::local_maxjitter, ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevrxploss, LOG_ERROR, LOG_WARNING, ast_rtp_instance_stats::maxrtt, ast_rtp_instance_stats::minrtt, name, ast_rtp_instance_stats::normdevrtt, NULL, parse(), sip_pvt::peername, sip_pvt::recv, ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, ast_rtp_instance_stats::remote_stdevrxploss, REQ_OFFSET_TO_STR, sip_pvt::rtp, ast_rtp_instance_stats::rtt, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, sip_pvt::sa, sip_pvt::socket, sip_pvt::srtp, t38properties::state, ast_rtp_instance_stats::stdevrtt, sip_pvt::t38, T38_DISABLED, sip_pvt::trtp, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, ast_rtp_instance_stats::txploss, type, sip_socket::type, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::vrtp.

128 {
129  struct sip_pvt *p = ast_channel_tech_pvt(chan);
130  char *parse = ast_strdupa(preparse);
131  int res = 0;
133  AST_APP_ARG(param);
134  AST_APP_ARG(type);
135  AST_APP_ARG(field);
136  );
137 
138  /* Check for zero arguments */
139  if (ast_strlen_zero(parse)) {
140  ast_log(LOG_ERROR, "Cannot call %s without arguments\n", funcname);
141  return -1;
142  }
143 
144  AST_STANDARD_APP_ARGS(args, parse);
145 
146  /* Sanity check */
147  if (!IS_SIP_TECH(ast_channel_tech(chan))) {
148  ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
149  return 0;
150  }
151 
152  memset(buf, 0, buflen);
153 
154  if (p == NULL) {
155  return -1;
156  }
157 
158  if (!strcasecmp(args.param, "peerip")) {
160  } else if (!strcasecmp(args.param, "recvip")) {
162  } else if (!strcasecmp(args.param, "recvport")) {
164  } else if (!strcasecmp(args.param, "from")) {
165  ast_copy_string(buf, p->from, buflen);
166  } else if (!strcasecmp(args.param, "uri")) {
167  ast_copy_string(buf, p->uri, buflen);
168  } else if (!strcasecmp(args.param, "ruri")) {
169  char *tmpruri = REQ_OFFSET_TO_STR(&p->initreq, rlpart2);
170  ast_copy_string(buf, tmpruri, buflen);
171  } else if (!strcasecmp(args.param, "useragent")) {
172  ast_copy_string(buf, p->useragent, buflen);
173  } else if (!strcasecmp(args.param, "peername")) {
174  ast_copy_string(buf, p->peername, buflen);
175  } else if (!strcasecmp(args.param, "t38passthrough")) {
176  ast_copy_string(buf, (p->t38.state == T38_DISABLED) ? "0" : "1", buflen);
177  } else if (!strcasecmp(args.param, "rtpdest")) {
178  struct ast_sockaddr addr;
179  struct ast_rtp_instance *stream;
180 
181  if (ast_strlen_zero(args.type))
182  args.type = "audio";
183 
184  if (!strcasecmp(args.type, "audio"))
185  stream = p->rtp;
186  else if (!strcasecmp(args.type, "video"))
187  stream = p->vrtp;
188  else if (!strcasecmp(args.type, "text"))
189  stream = p->trtp;
190  else
191  return -1;
192 
193  /* Return 0 to suppress a console warning message */
194  if (!stream) {
195  return 0;
196  }
197 
199  snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&addr));
200  } else if (!strcasecmp(args.param, "rtpsource")) {
201  struct ast_sockaddr sa;
202  struct ast_rtp_instance *stream;
203 
204  if (ast_strlen_zero(args.type))
205  args.type = "audio";
206 
207  if (!strcasecmp(args.type, "audio"))
208  stream = p->rtp;
209  else if (!strcasecmp(args.type, "video"))
210  stream = p->vrtp;
211  else if (!strcasecmp(args.type, "text"))
212  stream = p->trtp;
213  else
214  return -1;
215 
216  /* Return 0 to suppress a console warning message */
217  if (!stream) {
218  return 0;
219  }
220 
222 
223  if (ast_sockaddr_isnull(&sa)) {
224  struct ast_sockaddr dest_sa;
225  ast_rtp_instance_get_remote_address(stream, &dest_sa);
226  ast_ouraddrfor(&dest_sa, &sa);
227  }
228 
229  snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&sa));
230  } else if (!strcasecmp(args.param, "rtpqos")) {
231  struct ast_rtp_instance *rtp = NULL;
232 
233  if (ast_strlen_zero(args.type)) {
234  args.type = "audio";
235  }
236 
237  if (!strcasecmp(args.type, "audio")) {
238  rtp = p->rtp;
239  } else if (!strcasecmp(args.type, "video")) {
240  rtp = p->vrtp;
241  } else if (!strcasecmp(args.type, "text")) {
242  rtp = p->trtp;
243  } else {
244  return -1;
245  }
246 
247  if (ast_strlen_zero(args.field) || !strcasecmp(args.field, "all")) {
248  char quality_buf[AST_MAX_USER_FIELD];
249 
250  if (!ast_rtp_instance_get_quality(rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf))) {
251  return -1;
252  }
253 
254  ast_copy_string(buf, quality_buf, buflen);
255  return res;
256  } else {
257  struct ast_rtp_instance_stats stats;
258  int i;
259  struct {
260  const char *name;
261  enum { INT, DBL } type;
262  union {
263  unsigned int *i4;
264  double *d8;
265  };
266  } lookup[] = {
267  { "txcount", INT, { .i4 = &stats.txcount, }, },
268  { "rxcount", INT, { .i4 = &stats.rxcount, }, },
269  { "txjitter", DBL, { .d8 = &stats.txjitter, }, },
270  { "rxjitter", DBL, { .d8 = &stats.rxjitter, }, },
271  { "remote_maxjitter", DBL, { .d8 = &stats.remote_maxjitter, }, },
272  { "remote_minjitter", DBL, { .d8 = &stats.remote_minjitter, }, },
273  { "remote_normdevjitter", DBL, { .d8 = &stats.remote_normdevjitter, }, },
274  { "remote_stdevjitter", DBL, { .d8 = &stats.remote_stdevjitter, }, },
275  { "local_maxjitter", DBL, { .d8 = &stats.local_maxjitter, }, },
276  { "local_minjitter", DBL, { .d8 = &stats.local_minjitter, }, },
277  { "local_normdevjitter", DBL, { .d8 = &stats.local_normdevjitter, }, },
278  { "local_stdevjitter", DBL, { .d8 = &stats.local_stdevjitter, }, },
279  { "txploss", INT, { .i4 = &stats.txploss, }, },
280  { "rxploss", INT, { .i4 = &stats.rxploss, }, },
281  { "remote_maxrxploss", DBL, { .d8 = &stats.remote_maxrxploss, }, },
282  { "remote_minrxploss", DBL, { .d8 = &stats.remote_minrxploss, }, },
283  { "remote_normdevrxploss", DBL, { .d8 = &stats.remote_normdevrxploss, }, },
284  { "remote_stdevrxploss", DBL, { .d8 = &stats.remote_stdevrxploss, }, },
285  { "local_maxrxploss", DBL, { .d8 = &stats.local_maxrxploss, }, },
286  { "local_minrxploss", DBL, { .d8 = &stats.local_minrxploss, }, },
287  { "local_normdevrxploss", DBL, { .d8 = &stats.local_normdevrxploss, }, },
288  { "local_stdevrxploss", DBL, { .d8 = &stats.local_stdevrxploss, }, },
289  { "rtt", DBL, { .d8 = &stats.rtt, }, },
290  { "maxrtt", DBL, { .d8 = &stats.maxrtt, }, },
291  { "minrtt", DBL, { .d8 = &stats.minrtt, }, },
292  { "normdevrtt", DBL, { .d8 = &stats.normdevrtt, }, },
293  { "stdevrtt", DBL, { .d8 = &stats.stdevrtt, }, },
294  { "local_ssrc", INT, { .i4 = &stats.local_ssrc, }, },
295  { "remote_ssrc", INT, { .i4 = &stats.remote_ssrc, }, },
296  { NULL, },
297  };
298 
300  return -1;
301  }
302 
303  for (i = 0; !ast_strlen_zero(lookup[i].name); i++) {
304  if (!strcasecmp(args.field, lookup[i].name)) {
305  if (lookup[i].type == INT) {
306  snprintf(buf, buflen, "%u", *lookup[i].i4);
307  } else {
308  snprintf(buf, buflen, "%f", *lookup[i].d8);
309  }
310  return 0;
311  }
312  }
313  ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
314  return -1;
315  }
316  } else if (!strcasecmp(args.param, "secure_signaling")) {
317  snprintf(buf, buflen, "%s", p->socket.type == AST_TRANSPORT_TLS ? "1" : "");
318  } else if (!strcasecmp(args.param, "secure_media")) {
319  snprintf(buf, buflen, "%s", p->srtp ? "1" : "");
320  } else {
321  res = -1;
322  }
323  return res;
324 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
static const char type[]
Definition: chan_ooh323.c:109
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
enum t38state state
Definition: sip.h:917
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_rtp_instance * trtp
Definition: sip.h:1176
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
const ast_string_field from
Definition: sip.h:1063
const char * args
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
struct t38properties t38
Definition: sip.h:1113
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
struct ast_sockaddr sa
Definition: sip.h:1125
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:1005
#define ast_log
Definition: astobj2.c:42
struct sip_request initreq
Definition: sip.h:1151
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size)
Retrieve quality statistics about an RTP instance.
Definition: rtp_engine.c:2460
#define LOG_ERROR
Definition: logger.h:285
#define IS_SIP_TECH(t)
Definition: sip_utils.h:26
const ast_string_field useragent
Definition: sip.h:1063
#define T38_DISABLED
Definition: chan_ooh323.c:101
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
struct ast_rtp_instance * vrtp
Definition: sip.h:1175
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static const char name[]
Definition: cdr_mysql.c:74
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
struct ast_rtp_instance * rtp
Definition: sip.h:1174
const ast_string_field peername
Definition: sip.h:1063
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
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1192
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
const ast_string_field uri
Definition: sip.h:1063
#define AST_APP_ARG(name)
Define an application argument.
#define AST_MAX_USER_FIELD
Definition: channel.h:175

◆ sip_dialplan_function_register_tests()

void sip_dialplan_function_register_tests ( void  )

SIP test registration.

register dialplan function tests

Definition at line 502 of file sip/dialplan_functions.c.

References AST_TEST_REGISTER.

Referenced by sip_register_tests().

503 {
504  AST_TEST_REGISTER(test_sip_rtpqos_1);
505 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

◆ sip_dialplan_function_unregister_tests()

void sip_dialplan_function_unregister_tests ( void  )

SIP test registration.

unregister dialplan function tests

Definition at line 508 of file sip/dialplan_functions.c.

References AST_TEST_UNREGISTER.

Referenced by sip_unregister_tests().

509 {
510  AST_TEST_UNREGISTER(test_sip_rtpqos_1);
511 }
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

◆ test_sip_rtpqos_1_destroy()

static int test_sip_rtpqos_1_destroy ( struct ast_rtp_instance instance)
static

Definition at line 334 of file sip/dialplan_functions.c.

Referenced by AST_TEST_DEFINE().

335 {
336  /* Needed to pass sanity checks */
337  return 0;
338 }

◆ test_sip_rtpqos_1_get_stat()

static int test_sip_rtpqos_1_get_stat ( struct ast_rtp_instance instance,
struct ast_rtp_instance_stats stats,
enum ast_rtp_instance_stat  stat 
)
static

Definition at line 352 of file sip/dialplan_functions.c.

References ast_rtp_instance_get_data().

Referenced by AST_TEST_DEFINE().

353 {
355  memcpy(stats, s, sizeof(*stats));
356  return 0;
357 }
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:563

◆ test_sip_rtpqos_1_new()

static int test_sip_rtpqos_1_new ( struct ast_rtp_instance instance,
struct ast_sched_context sched,
struct ast_sockaddr addr,
void *  data 
)
static

Definition at line 327 of file sip/dialplan_functions.c.

References ast_rtp_instance_set_data().

Referenced by AST_TEST_DEFINE().

328 {
329  /* Needed to pass sanity checks */
330  ast_rtp_instance_set_data(instance, data);
331  return 0;
332 }
void ast_rtp_instance_set_data(struct ast_rtp_instance *instance, void *data)
Set the data portion of an RTP instance.
Definition: rtp_engine.c:558

◆ test_sip_rtpqos_1_read()

static struct ast_frame* test_sip_rtpqos_1_read ( struct ast_rtp_instance instance,
int  rtcp 
)
static

Definition at line 340 of file sip/dialplan_functions.c.

References ast_null_frame.

Referenced by AST_TEST_DEFINE().

341 {
342  /* Needed to pass sanity checks */
343  return &ast_null_frame;
344 }
struct ast_frame ast_null_frame
Definition: main/frame.c:79

◆ test_sip_rtpqos_1_write()

static int test_sip_rtpqos_1_write ( struct ast_rtp_instance instance,
struct ast_frame frame 
)
static

Definition at line 346 of file sip/dialplan_functions.c.

Referenced by AST_TEST_DEFINE().

347 {
348  /* Needed to pass sanity checks */
349  return 0;
350 }