Asterisk - The Open Source Telephony Project  GIT-master-a1fa8df
sip/dialplan_functions.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16 
17 /*!
18  * \file
19  * \brief sip channel dialplan functions and unit tests
20  */
21 
22 /*** MODULEINFO
23  <support_level>deprecated</support_level>
24  ***/
25 
26 /*** DOCUMENTATION
27 <info name="CHANNEL" language="en_US" tech="SIP">
28  <enumlist>
29  <enum name="peerip">
30  <para>R/O Get the IP address of the peer.</para>
31  </enum>
32  <enum name="recvip">
33  <para>R/O Get the source IP address of the peer.</para>
34  </enum>
35  <enum name="recvport">
36  <para>R/O Get the source port of the peer.</para>
37  </enum>
38  <enum name="from">
39  <para>R/O Get the URI from the From: header.</para>
40  </enum>
41  <enum name="uri">
42  <para>R/O Get the URI from the Contact: header.</para>
43  </enum>
44  <enum name="ruri">
45  <para>R/O Get the Request-URI from the INVITE header.</para>
46  </enum>
47  <enum name="useragent">
48  <para>R/O Get the useragent.</para>
49  </enum>
50  <enum name="peername">
51  <para>R/O Get the name of the peer.</para>
52  </enum>
53  <enum name="t38passthrough">
54  <para>R/O <literal>1</literal> if T38 is offered or enabled in this channel,
55  otherwise <literal>0</literal></para>
56  </enum>
57  <enum name="rtpqos">
58  <para>R/O Get QOS information about the RTP stream</para>
59  <para> This option takes two additional arguments:</para>
60  <para> Argument 1:</para>
61  <para> <literal>audio</literal> Get data about the audio stream</para>
62  <para> <literal>video</literal> Get data about the video stream</para>
63  <para> <literal>text</literal> Get data about the text stream</para>
64  <para> Argument 2:</para>
65  <para> <literal>local_ssrc</literal> Local SSRC (stream ID)</para>
66  <para> <literal>local_lostpackets</literal> Local lost packets</para>
67  <para> <literal>local_jitter</literal> Local calculated jitter</para>
68  <para> <literal>local_maxjitter</literal> Local calculated jitter (maximum)</para>
69  <para> <literal>local_minjitter</literal> Local calculated jitter (minimum)</para>
70  <para> <literal>local_normdevjitter</literal>Local calculated jitter (normal deviation)</para>
71  <para> <literal>local_stdevjitter</literal> Local calculated jitter (standard deviation)</para>
72  <para> <literal>local_count</literal> Number of received packets</para>
73  <para> <literal>remote_ssrc</literal> Remote SSRC (stream ID)</para>
74  <para> <literal>remote_lostpackets</literal>Remote lost packets</para>
75  <para> <literal>remote_jitter</literal> Remote reported jitter</para>
76  <para> <literal>remote_maxjitter</literal> Remote calculated jitter (maximum)</para>
77  <para> <literal>remote_minjitter</literal> Remote calculated jitter (minimum)</para>
78  <para> <literal>remote_normdevjitter</literal>Remote calculated jitter (normal deviation)</para>
79  <para> <literal>remote_stdevjitter</literal>Remote calculated jitter (standard deviation)</para>
80  <para> <literal>remote_count</literal> Number of transmitted packets</para>
81  <para> <literal>rtt</literal> Round trip time</para>
82  <para> <literal>maxrtt</literal> Round trip time (maximum)</para>
83  <para> <literal>minrtt</literal> Round trip time (minimum)</para>
84  <para> <literal>normdevrtt</literal> Round trip time (normal deviation)</para>
85  <para> <literal>stdevrtt</literal> Round trip time (standard deviation)</para>
86  <para> <literal>all</literal> All statistics (in a form suited to logging,
87  but not for parsing)</para>
88  </enum>
89  <enum name="rtpdest">
90  <para>R/O Get remote RTP destination information.</para>
91  <para> This option takes one additional argument:</para>
92  <para> Argument 1:</para>
93  <para> <literal>audio</literal> Get audio destination</para>
94  <para> <literal>video</literal> Get video destination</para>
95  <para> <literal>text</literal> Get text destination</para>
96  <para> Defaults to <literal>audio</literal> if unspecified.</para>
97  </enum>
98  <enum name="rtpsource">
99  <para>R/O Get source RTP destination information.</para>
100  <para> This option takes one additional argument:</para>
101  <para> Argument 1:</para>
102  <para> <literal>audio</literal> Get audio destination</para>
103  <para> <literal>video</literal> Get video destination</para>
104  <para> <literal>text</literal> Get text destination</para>
105  <para> Defaults to <literal>audio</literal> if unspecified.</para>
106  </enum>
107  </enumlist>
108 </info>
109  ***/
110 
111 #include "asterisk.h"
112 
113 #include <math.h>
114 
115 #include "asterisk/channel.h"
116 #include "asterisk/rtp_engine.h"
117 #include "asterisk/pbx.h"
118 #include "asterisk/acl.h"
119 
120 #include "include/sip.h"
121 #include "include/globals.h"
122 #include "include/dialog.h"
123 #include "include/dialplan_functions.h"
124 #include "include/sip_utils.h"
125 
126 
127 int sip_acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
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 }
325 
326 #ifdef TEST_FRAMEWORK
327 static int test_sip_rtpqos_1_new(struct ast_rtp_instance *instance, struct ast_sched_context *sched, struct ast_sockaddr *addr, void *data)
328 {
329  /* Needed to pass sanity checks */
330  ast_rtp_instance_set_data(instance, data);
331  return 0;
332 }
333 
334 static int test_sip_rtpqos_1_destroy(struct ast_rtp_instance *instance)
335 {
336  /* Needed to pass sanity checks */
337  return 0;
338 }
339 
340 static struct ast_frame *test_sip_rtpqos_1_read(struct ast_rtp_instance *instance, int rtcp)
341 {
342  /* Needed to pass sanity checks */
343  return &ast_null_frame;
344 }
345 
346 static int test_sip_rtpqos_1_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
347 {
348  /* Needed to pass sanity checks */
349  return 0;
350 }
351 
352 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)
353 {
355  memcpy(stats, s, sizeof(*stats));
356  return 0;
357 }
358 
359 AST_TEST_DEFINE(test_sip_rtpqos_1)
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 }
499 #endif
500 
501 /*! \brief SIP test registration */
503 {
504  AST_TEST_REGISTER(test_sip_rtpqos_1);
505 }
506 
507 /*! \brief SIP test registration */
509 {
510  AST_TEST_UNREGISTER(test_sip_rtpqos_1);
511 }
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
void sip_dialplan_function_register_tests(void)
SIP test registration.
chan_sip header file
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
static const char name[]
Definition: format_mp3.c:68
Asterisk main include file. File version handling, generic pbx functions.
#define ast_rtp_engine_register(engine)
Definition: rtp_engine.h:794
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)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
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
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct ast_sockaddr recv
Definition: sip.h:1135
struct sip_socket socket
Definition: sip.h:1066
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
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
unsigned int rxploss
Definition: rtp_engine.h:394
const ast_string_field from
Definition: sip.h:1063
const char * args
#define NULL
Definition: resample.c:96
void sip_dialplan_function_unregister_tests(void)
SIP test registration.
Socket address structure.
Definition: netsock2.h:97
sip global declaration header file
struct t38properties t38
Definition: sip.h:1113
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
int done
Definition: test_amihooks.c:48
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
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:3371
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
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
General Asterisk PBX channel definitions.
int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
Unregister an RTP engine.
Definition: rtp_engine.c:364
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
ast_rtp_instance_stat
Definition: rtp_engine.h:180
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
struct sip_request initreq
Definition: sip.h:1151
Access Control of various sorts.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid)
Definition: dialog.h:39
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
Core PBX routines and definitions.
unsigned int rxcount
Definition: rtp_engine.h:370
#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
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 AST_TEST_UNREGISTER(cb)
Definition: test.h:128
#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)
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.
#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:1844
unsigned int txploss
Definition: rtp_engine.h:392
#define ast_free(a)
Definition: astmm.h:182
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:563
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
#define REQ_OFFSET_TO_STR(req, offset)
Definition: sip.h:858
sip dialog management header file
const char * name
Definition: rtp_engine.h:616
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
struct ast_frame ast_null_frame
Definition: main/frame.c:79
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
Data structure associated with a single frame of data.
#define AST_TEST_DEFINE(hdr)
Definition: test.h:126
struct ast_channel_tech sip_tech
Definition of this channel for PBX channel registration.
Definition: chan_sip.c:1577
struct ast_sdp_srtp * srtp
Definition: sip.h:1185
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
Pluggable RTP Architecture.
sip utils header file
#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
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
#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
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
#define AST_APP_ARG(name)
Define an application argument.
#define AST_MAX_USER_FIELD
Definition: channel.h:175