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

SIP dialplan functions header file. More...

#include "sip.h"
Include dependency graph for sip/include/dialplan_functions.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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)
 register dialplan function tests More...
 
void sip_dialplan_function_unregister_tests (void)
 unregister dialplan function tests More...
 

Detailed Description

SIP dialplan functions header file.

Definition in file sip/include/dialplan_functions.h.

Function Documentation

◆ 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 'standard' 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'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  )

register dialplan function tests

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  )

unregister dialplan function tests

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