Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Functions | Variables
pjsip/dialplan_functions.c File Reference

PJSIP channel dialplan functions. More...

#include "asterisk.h"
#include <pjsip.h>
#include <pjlib.h>
#include <pjsip_ua.h>
#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/acl.h"
#include "asterisk/app.h"
#include "asterisk/channel.h"
#include "asterisk/stream.h"
#include "asterisk/format.h"
#include "asterisk/dsp.h"
#include "asterisk/pbx.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "include/chan_pjsip.h"
#include "include/dialplan_functions.h"
Include dependency graph for pjsip/dialplan_functions.c:

Go to the source code of this file.

Data Structures

struct  media_offer_data
 
struct  parse_uri_args
 Struct used to push PJSIP_PARSE_URI function arguments to task processor. More...
 
struct  pjsip_func_args
 Struct used to push function arguments to task processor. More...
 
struct  refresh_data
 
struct  session_refresh_state
 Session refresh state information. More...
 

Functions

static int channel_read_pjsip (struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
 
static int channel_read_rtcp (struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
 
static int channel_read_rtp (struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
 
static int dtmf_mode_refresh_cb (void *obj)
 
static int media_offer_read_av (struct ast_sip_session *session, char *buf, size_t len, enum ast_media_type media_type)
 
static int media_offer_write_av (void *obj)
 
static int parse_uri_cb (void *data)
 
int pjsip_acf_channel_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 CHANNEL function read callback. More...
 
int pjsip_acf_dial_contacts_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 PJSIP_DIAL_CONTACTS function read callback. More...
 
int pjsip_acf_dtmf_mode_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 PJSIP_DTMF_MODE function read callback. More...
 
int pjsip_acf_dtmf_mode_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 PJSIP_DTMF_MODE function write callback. More...
 
int pjsip_acf_media_offer_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 PJSIP_MEDIA_OFFER function read callback. More...
 
int pjsip_acf_media_offer_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 PJSIP_MEDIA_OFFER function write callback. More...
 
int pjsip_acf_moh_passthrough_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 PJSIP_MOH_PASSTHROUGH function read callback. More...
 
int pjsip_acf_moh_passthrough_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 PJSIP_MOH_PASSTHROUGH function write callback. More...
 
int pjsip_acf_parse_uri_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
 PJSIP_PARSE_URI function read callback. More...
 
int pjsip_acf_session_refresh_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 PJSIP_SEND_SESSION_REFRESH function write callback. More...
 
static int print_escaped_uri (struct ast_channel *chan, const char *type, pjsip_uri_context_e context, const void *uri, char *buf, size_t size)
 
static int read_pjsip (void *data)
 
static int refresh_write_cb (void *obj)
 
static void session_refresh_state_destroy (void *obj)
 Destructor for session refresh information. More...
 
static struct session_refresh_statesession_refresh_state_get_or_alloc (struct ast_sip_session *session)
 Helper function which retrieves or allocates a session refresh state information datastore. More...
 
static int sip_session_response_cb (struct ast_sip_session *session, pjsip_rx_data *rdata)
 

Variables

static const struct ast_datastore_info session_refresh_datastore
 Datastore for attaching session refresh state information. More...
 
static const char * t38state_to_string [T38_MAX_ENUM]
 String representations of the T.38 state enum. More...
 

Detailed Description

PJSIP channel dialplan functions.

Author
Joshua Colp <jcolp@digium.com> 
Matt Jordan <mjordan@digium.com> 

Definition in file pjsip/dialplan_functions.c.

Function Documentation

◆ channel_read_pjsip()

static int channel_read_pjsip ( struct ast_channel chan,
const char *  type,
const char *  field,
char *  buf,
size_t  buflen 
)
static

Definition at line 776 of file pjsip/dialplan_functions.c.

777 {
778  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
779  char *buf_copy;
780  pjsip_dialog *dlg;
781  int res = 0;
782 
783  if (!channel) {
784  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
785  return -1;
786  }
787 
788  dlg = channel->session->inv_session->dlg;
789 
790  if (ast_strlen_zero(type)) {
791  ast_log(LOG_WARNING, "You must supply a type field for 'pjsip' information\n");
792  return -1;
793  } else if (!strcmp(type, "call-id")) {
794  snprintf(buf, buflen, "%.*s", (int) pj_strlen(&dlg->call_id->id), pj_strbuf(&dlg->call_id->id));
795  } else if (!strcmp(type, "secure")) {
796 #ifdef HAVE_PJSIP_GET_DEST_INFO
797  pjsip_host_info dest;
798  pj_pool_t *pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "secure-check", 128, 128);
799  pjsip_get_dest_info(dlg->target, NULL, pool, &dest);
800  snprintf(buf, buflen, "%d", dest.flag & PJSIP_TRANSPORT_SECURE ? 1 : 0);
801  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
802 #else
803  ast_log(LOG_WARNING, "Asterisk has been built against a version of pjproject which does not have the required functionality to support the 'secure' argument. Please upgrade to version 2.3 or later.\n");
804  return -1;
805 #endif
806  } else if (!strcmp(type, "target_uri")) {
807  res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf,
808  buflen);
809  } else if (!strcmp(type, "local_uri")) {
810  res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri,
811  buf, buflen);
812  } else if (!strcmp(type, "local_tag")) {
813  ast_copy_pj_str(buf, &dlg->local.info->tag, buflen);
814  buf_copy = ast_strdupa(buf);
815  ast_escape_quoted(buf_copy, buf, buflen);
816  } else if (!strcmp(type, "remote_uri")) {
817  res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR,
818  dlg->remote.info->uri, buf, buflen);
819  } else if (!strcmp(type, "remote_tag")) {
820  ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen);
821  buf_copy = ast_strdupa(buf);
822  ast_escape_quoted(buf_copy, buf, buflen);
823  } else if (!strcmp(type, "request_uri")) {
824  if (channel->session->request_uri) {
825  res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI,
826  channel->session->request_uri, buf, buflen);
827  }
828  } else if (!strcmp(type, "t38state")) {
830  } else if (!strcmp(type, "local_addr")) {
831  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
832  struct transport_info_data *transport_data;
833 
834  datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
835  if (!datastore) {
836  ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
837  return -1;
838  }
839  transport_data = datastore->data;
840 
841  if (pj_sockaddr_has_addr(&transport_data->local_addr)) {
842  pj_sockaddr_print(&transport_data->local_addr, buf, buflen, 3);
843  }
844  } else if (!strcmp(type, "remote_addr")) {
845  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
846  struct transport_info_data *transport_data;
847 
848  datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
849  if (!datastore) {
850  ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
851  return -1;
852  }
853  transport_data = datastore->data;
854 
855  if (pj_sockaddr_has_addr(&transport_data->remote_addr)) {
856  pj_sockaddr_print(&transport_data->remote_addr, buf, buflen, 3);
857  }
858  } else {
859  ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'pjsip' information\n", type);
860  return -1;
861  }
862 
863  return res;
864 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
static const char type[]
Definition: chan_ooh323.c:109
void * ast_channel_tech_pvt(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_LOG_WARNING
#define LOG_WARNING
static int print_escaped_uri(struct ast_channel *chan, const char *type, pjsip_uri_context_e context, const void *uri, char *buf, size_t size)
static const char * t38state_to_string[T38_MAX_ENUM]
String representations of the T.38 state enum.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:513
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:2035
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
Structure for a data store object.
Definition: datastore.h:64
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
pjsip_uri * request_uri
enum ast_sip_session_t38state t38state
struct pjsip_inv_session * inv_session
Transport information stored in transport_info datastore.
Definition: chan_pjsip.h:30
pj_sockaddr local_addr
Our address that received the request.
Definition: chan_pjsip.h:34
pj_sockaddr remote_addr
The address that sent the request.
Definition: chan_pjsip.h:32
#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:936
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:781

References ao2_cleanup, ast_channel_name(), ast_channel_tech_pvt(), ast_copy_pj_str(), ast_copy_string(), ast_escape_quoted(), ast_log, AST_LOG_WARNING, ast_sip_get_pjsip_endpoint(), ast_sip_session_get_datastore(), ast_strdupa, ast_strlen_zero(), buf, ast_sip_session::inv_session, transport_info_data::local_addr, LOG_WARNING, NULL, print_escaped_uri(), RAII_VAR, transport_info_data::remote_addr, ast_sip_session::request_uri, ast_sip_channel_pvt::session, ast_sip_session::t38state, t38state_to_string, and type.

Referenced by read_pjsip().

◆ channel_read_rtcp()

static int channel_read_rtcp ( struct ast_channel chan,
const char *  type,
const char *  field,
char *  buf,
size_t  buflen 
)
static

Definition at line 635 of file pjsip/dialplan_functions.c.

636 {
637  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
638  struct ast_sip_session *session;
639  struct ast_sip_session_media *media;
640 
641  if (!channel) {
642  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
643  return -1;
644  }
645 
646  session = channel->session;
647  if (!session) {
648  ast_log(AST_LOG_WARNING, "Channel %s has no session!\n", ast_channel_name(chan));
649  return -1;
650  }
651 
652  if (ast_strlen_zero(type)) {
653  ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtcp' information\n");
654  return -1;
655  }
656 
657  if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
658  media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
659  } else if (!strcmp(field, "video")) {
660  media = session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO];
661  } else {
662  ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtcp' information\n", field);
663  return -1;
664  }
665 
666  if (!media || !media->rtp) {
667  ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
668  ast_channel_name(chan), S_OR(field, "audio"));
669  return -1;
670  }
671 
672  if (!strncasecmp(type, "all", 3)) {
674 
675  if (!strcasecmp(type, "all_jitter")) {
677  } else if (!strcasecmp(type, "all_rtt")) {
679  } else if (!strcasecmp(type, "all_loss")) {
681  }
682 
683  if (!ast_rtp_instance_get_quality(media->rtp, stat_field, buf, buflen)) {
684  ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
685  return -1;
686  }
687  } else {
688  struct ast_rtp_instance_stats stats;
689  int i;
690  struct {
691  const char *name;
692  enum { INT, DBL } type;
693  union {
694  unsigned int *i4;
695  double *d8;
696  };
697  } lookup[] = {
698  { "txcount", INT, { .i4 = &stats.txcount, }, },
699  { "rxcount", INT, { .i4 = &stats.rxcount, }, },
700  { "txjitter", DBL, { .d8 = &stats.txjitter, }, },
701  { "rxjitter", DBL, { .d8 = &stats.rxjitter, }, },
702  { "remote_maxjitter", DBL, { .d8 = &stats.remote_maxjitter, }, },
703  { "remote_minjitter", DBL, { .d8 = &stats.remote_minjitter, }, },
704  { "remote_normdevjitter", DBL, { .d8 = &stats.remote_normdevjitter, }, },
705  { "remote_stdevjitter", DBL, { .d8 = &stats.remote_stdevjitter, }, },
706  { "local_maxjitter", DBL, { .d8 = &stats.local_maxjitter, }, },
707  { "local_minjitter", DBL, { .d8 = &stats.local_minjitter, }, },
708  { "local_normdevjitter", DBL, { .d8 = &stats.local_normdevjitter, }, },
709  { "local_stdevjitter", DBL, { .d8 = &stats.local_stdevjitter, }, },
710  { "txploss", INT, { .i4 = &stats.txploss, }, },
711  { "rxploss", INT, { .i4 = &stats.rxploss, }, },
712  { "remote_maxrxploss", DBL, { .d8 = &stats.remote_maxrxploss, }, },
713  { "remote_minrxploss", DBL, { .d8 = &stats.remote_minrxploss, }, },
714  { "remote_normdevrxploss", DBL, { .d8 = &stats.remote_normdevrxploss, }, },
715  { "remote_stdevrxploss", DBL, { .d8 = &stats.remote_stdevrxploss, }, },
716  { "local_maxrxploss", DBL, { .d8 = &stats.local_maxrxploss, }, },
717  { "local_minrxploss", DBL, { .d8 = &stats.local_minrxploss, }, },
718  { "local_normdevrxploss", DBL, { .d8 = &stats.local_normdevrxploss, }, },
719  { "local_stdevrxploss", DBL, { .d8 = &stats.local_stdevrxploss, }, },
720  { "rtt", DBL, { .d8 = &stats.rtt, }, },
721  { "maxrtt", DBL, { .d8 = &stats.maxrtt, }, },
722  { "minrtt", DBL, { .d8 = &stats.minrtt, }, },
723  { "normdevrtt", DBL, { .d8 = &stats.normdevrtt, }, },
724  { "stdevrtt", DBL, { .d8 = &stats.stdevrtt, }, },
725  { "local_ssrc", INT, { .i4 = &stats.local_ssrc, }, },
726  { "remote_ssrc", INT, { .i4 = &stats.remote_ssrc, }, },
727  { NULL, },
728  };
729 
731  ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
732  return -1;
733  }
734 
735  for (i = 0; !ast_strlen_zero(lookup[i].name); i++) {
736  if (!strcasecmp(type, lookup[i].name)) {
737  if (lookup[i].type == INT) {
738  snprintf(buf, buflen, "%u", *lookup[i].i4);
739  } else {
740  snprintf(buf, buflen, "%f", *lookup[i].d8);
741  }
742  return 0;
743  }
744  }
745  ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'rtcp' information\n", type);
746  return -1;
747  }
748 
749  return 0;
750 }
static struct ast_mansession session
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
static const char name[]
Definition: format_mp3.c:68
ast_rtp_instance_stat_field
Definition: rtp_engine.h:168
@ AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS
Definition: rtp_engine.h:174
@ AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT
Definition: rtp_engine.h:176
@ AST_RTP_INSTANCE_STAT_FIELD_QUALITY
Definition: rtp_engine.h:170
@ AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER
Definition: rtp_engine.h:172
@ AST_RTP_INSTANCE_STAT_ALL
Definition: rtp_engine.h:182
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:2438
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:2452
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
A structure describing a SIP session.

References ast_channel_name(), ast_channel_tech_pvt(), ast_log, AST_LOG_WARNING, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, ast_rtp_instance_get_quality(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_strlen_zero(), buf, 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_instance_stats::normdevrtt, NULL, 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, ast_sip_session_media::rtp, ast_rtp_instance_stats::rtt, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, S_OR, ast_sip_channel_pvt::session, session, ast_rtp_instance_stats::stdevrtt, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, ast_rtp_instance_stats::txploss, and type.

Referenced by read_pjsip().

◆ channel_read_rtp()

static int channel_read_rtp ( struct ast_channel chan,
const char *  type,
const char *  field,
char *  buf,
size_t  buflen 
)
static

Definition at line 568 of file pjsip/dialplan_functions.c.

569 {
570  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
571  struct ast_sip_session *session;
572  struct ast_sip_session_media *media;
573  struct ast_sockaddr addr;
574 
575  if (!channel) {
576  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
577  return -1;
578  }
579 
580  session = channel->session;
581  if (!session) {
582  ast_log(AST_LOG_WARNING, "Channel %s has no session!\n", ast_channel_name(chan));
583  return -1;
584  }
585 
586  if (ast_strlen_zero(type)) {
587  ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtp' information\n");
588  return -1;
589  }
590 
591  if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
592  media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
593  } else if (!strcmp(field, "video")) {
594  media = session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO];
595  } else {
596  ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtp' information\n", field);
597  return -1;
598  }
599 
600  if (!media || !media->rtp) {
601  ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
602  ast_channel_name(chan), S_OR(field, "audio"));
603  return -1;
604  }
605 
606  if (!strcmp(type, "src")) {
608  ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
609  } else if (!strcmp(type, "dest")) {
611  ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
612  } else if (!strcmp(type, "direct")) {
614  } else if (!strcmp(type, "secure")) {
615  if (media->srtp) {
616  struct ast_sdp_srtp *srtp = media->srtp;
618  snprintf(buf, buflen, "%d", flag ? 1 : 0);
619  } else {
620  snprintf(buf, buflen, "%d", 0);
621  }
622  } else if (!strcmp(type, "hold")) {
623  snprintf(buf, buflen, "%d", media->remotely_held ? 1 : 0);
624  } else {
625  ast_log(AST_LOG_WARNING, "Unknown type field '%s' specified for 'rtp' information\n", type);
626  return -1;
627  }
628 
629  return 0;
630 }
long int flag
Definition: f2c.h:83
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#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_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
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:45
structure for secure RTP audio
Definition: sdp_srtp.h:38
struct ast_sdp_srtp * srtp
Holds SRTP information.
unsigned int remotely_held
Stream is on hold by remote side.
struct ast_sockaddr direct_media_addr
Direct media address.
Socket address structure.
Definition: netsock2.h:97
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_channel_name(), ast_channel_tech_pvt(), ast_copy_string(), ast_log, AST_LOG_WARNING, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address, ast_sockaddr_stringify(), AST_SRTP_CRYPTO_OFFER_OK, ast_strlen_zero(), ast_test_flag, buf, ast_sip_session_media::direct_media_addr, ast_sip_session_media::remotely_held, ast_sip_session_media::rtp, S_OR, ast_sip_channel_pvt::session, session, ast_sip_session_media::srtp, and type.

Referenced by read_pjsip().

◆ dtmf_mode_refresh_cb()

static int dtmf_mode_refresh_cb ( void *  obj)
static

Definition at line 1529 of file pjsip/dialplan_functions.c.

1530 {
1531  struct refresh_data *data = obj;
1532 
1533  if (data->session->inv_session->state == PJSIP_INV_STATE_CONFIRMED) {
1534  ast_debug(3, "Changing DTMF mode on channel %s after OFFER/ANSWER completion. Sending session refresh\n", ast_channel_name(data->session->channel));
1535 
1537  sip_session_response_cb, data->method, 1, NULL);
1538  } else if (data->session->inv_session->state == PJSIP_INV_STATE_INCOMING) {
1539  ast_debug(3, "Changing DTMF mode on channel %s during OFFER/ANSWER exchange. Updating SDP answer\n", ast_channel_name(data->session->channel));
1541  }
1542 
1543  return 0;
1544 }
#define ast_debug(level,...)
Log a DEBUG message.
static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
int ast_sip_session_regenerate_answer(struct ast_sip_session *session, ast_sip_session_sdp_creation_cb on_sdp_creation)
Regenerate SDP Answer.
int ast_sip_session_refresh(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *media_state)
Send a reinvite or UPDATE on a session.
struct ast_channel * channel
struct ast_sip_session * session
enum ast_sip_session_refresh_method method

References ast_channel_name(), ast_debug, ast_sip_session_refresh(), ast_sip_session_regenerate_answer(), ast_sip_session::channel, ast_sip_session::inv_session, refresh_data::method, NULL, refresh_data::session, and sip_session_response_cb().

Referenced by pjsip_acf_dtmf_mode_write().

◆ media_offer_read_av()

static int media_offer_read_av ( struct ast_sip_session session,
char *  buf,
size_t  len,
enum ast_media_type  media_type 
)
static

Definition at line 1248 of file pjsip/dialplan_functions.c.

1250 {
1251  struct ast_stream_topology *topology;
1252  int idx;
1253  struct ast_stream *stream = NULL;
1254  const struct ast_format_cap *caps;
1255  size_t accum = 0;
1256 
1257  if (session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
1258  struct session_refresh_state *state;
1259 
1260  /* As we've already answered we need to store our media state until we are ready to send it */
1262  if (!state) {
1263  return -1;
1264  }
1265  topology = state->media_state->topology;
1266  } else {
1267  /* The session is not yet up so we are initially answering or offering */
1268  if (!session->pending_media_state->topology) {
1269  session->pending_media_state->topology = ast_stream_topology_clone(session->endpoint->media.topology);
1270  if (!session->pending_media_state->topology) {
1271  return -1;
1272  }
1273  }
1274  topology = session->pending_media_state->topology;
1275  }
1276 
1277  /* Find the first suitable stream */
1278  for (idx = 0; idx < ast_stream_topology_get_count(topology); ++idx) {
1279  stream = ast_stream_topology_get_stream(topology, idx);
1280 
1281  if (ast_stream_get_type(stream) != media_type ||
1283  stream = NULL;
1284  continue;
1285  }
1286 
1287  break;
1288  }
1289 
1290  /* If no suitable stream then exit early */
1291  if (!stream) {
1292  buf[0] = '\0';
1293  return 0;
1294  }
1295 
1296  caps = ast_stream_get_formats(stream);
1297 
1298  /* Note: buf is not terminated while the string is being built. */
1299  for (idx = 0; idx < ast_format_cap_count(caps); ++idx) {
1300  struct ast_format *fmt;
1301  size_t size;
1302 
1303  fmt = ast_format_cap_get_format(caps, idx);
1304 
1305  /* Add one for a comma or terminator */
1306  size = strlen(ast_format_get_name(fmt)) + 1;
1307  if (len < size) {
1308  ao2_ref(fmt, -1);
1309  break;
1310  }
1311 
1312  /* Append the format name */
1313  strcpy(buf + accum, ast_format_get_name(fmt));/* Safe */
1314  ao2_ref(fmt, -1);
1315 
1316  accum += size;
1317  len -= size;
1318 
1319  /* The last comma on the built string will be set to the terminator. */
1320  buf[accum - 1] = ',';
1321  }
1322 
1323  /* Remove the trailing comma or terminate an empty buffer. */
1324  buf[accum ? accum - 1 : 0] = '\0';
1325  return 0;
1326 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
enum sip_cc_notify_state state
Definition: chan_sip.c:966
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static struct session_refresh_state * session_refresh_state_get_or_alloc(struct ast_sip_session *session)
Helper function which retrieves or allocates a session refresh state information datastore.
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream....
Definition: sip.h:486
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
@ AST_STREAM_STATE_REMOVED
Set when the stream has been removed/declined.
Definition: stream.h:78
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
Session refresh state information.

References ao2_ref, ast_format_cap_count(), ast_format_cap_get_format(), ast_format_get_name(), ast_stream_get_formats(), ast_stream_get_state(), ast_stream_get_type(), AST_STREAM_STATE_REMOVED, ast_stream_topology_clone(), ast_stream_topology_get_count(), ast_stream_topology_get_stream(), buf, len(), NULL, session, session_refresh_state_get_or_alloc(), and state.

Referenced by pjsip_acf_media_offer_read().

◆ media_offer_write_av()

static int media_offer_write_av ( void *  obj)
static

Definition at line 1334 of file pjsip/dialplan_functions.c.

1335 {
1336  struct media_offer_data *data = obj;
1337  struct ast_stream_topology *topology;
1338  struct ast_stream *stream;
1339  struct ast_format_cap *caps;
1340 
1341  if (data->session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
1342  struct session_refresh_state *state;
1343 
1344  /* As we've already answered we need to store our media state until we are ready to send it */
1346  if (!state) {
1347  return -1;
1348  }
1349  topology = state->media_state->topology;
1350  } else {
1351  /* The session is not yet up so we are initially answering or offering */
1352  if (!data->session->pending_media_state->topology) {
1354  if (!data->session->pending_media_state->topology) {
1355  return -1;
1356  }
1357  }
1358  topology = data->session->pending_media_state->topology;
1359  }
1360 
1361  /* XXX This method won't work when it comes time to do multistream support. The proper way to do this
1362  * will either be to
1363  * a) Alter all media streams of a particular type.
1364  * b) Change the dialplan function to be able to specify which stream to alter and alter only that
1365  * one stream
1366  */
1367  stream = ast_stream_topology_get_first_stream_by_type(topology, data->media_type);
1368  if (!stream) {
1369  return 0;
1370  }
1371 
1373  if (!caps) {
1374  return -1;
1375  }
1376 
1381  ast_stream_set_formats(stream, caps);
1382  ast_stream_set_metadata(stream, "pjsip_session_refresh", "force");
1383  ao2_ref(caps, -1);
1384 
1385  return 0;
1386 }
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:523
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
struct ast_stream * ast_stream_topology_get_first_stream_by_type(const struct ast_stream_topology *topology, enum ast_media_type type)
Gets the first active stream of a specific type from the topology.
Definition: stream.c:964
int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
Set a stream metadata value.
Definition: stream.c:460
void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
Set the current negotiated formats of a stream.
Definition: stream.c:365
struct ast_stream_topology * topology
Definition: res_pjsip.h:814
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:887
struct ast_stream_topology * topology
The media stream topology.
struct ast_sip_endpoint * endpoint
struct ast_sip_session_media_state * pending_media_state
enum ast_media_type media_type
struct ast_sip_session * session

References ao2_ref, ast_format_cap_alloc, ast_format_cap_append_from_cap(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_remove_by_type(), ast_format_cap_update_by_allow_disallow(), AST_MEDIA_TYPE_UNKNOWN, ast_stream_get_formats(), ast_stream_set_formats(), ast_stream_set_metadata(), ast_stream_topology_clone(), ast_stream_topology_get_first_stream_by_type(), ast_sip_session::endpoint, ast_sip_session::inv_session, ast_sip_endpoint::media, media_offer_data::media_type, ast_sip_session::pending_media_state, media_offer_data::session, session_refresh_state_get_or_alloc(), state, ast_sip_endpoint_media_configuration::topology, ast_sip_session_media_state::topology, and media_offer_data::value.

Referenced by pjsip_acf_media_offer_write().

◆ parse_uri_cb()

static int parse_uri_cb ( void *  data)
static

Definition at line 1137 of file pjsip/dialplan_functions.c.

1138 {
1139  struct parse_uri_args *args = data;
1140  pj_pool_t *pool;
1141  pjsip_name_addr *uri;
1142  pjsip_sip_uri *sip_uri;
1143  pj_str_t tmp;
1144 
1145  args->ret = 0;
1146 
1147  pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "ParseUri", 128, 128);
1148  if (!pool) {
1149  ast_log(LOG_ERROR, "Failed to allocate ParseUri endpoint pool.\n");
1150  args->ret = -1;
1151  return 0;
1152  }
1153 
1154  pj_strdup2_with_null(pool, &tmp, args->uri);
1155  uri = (pjsip_name_addr *)pjsip_parse_uri(pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
1156  if (!uri || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
1157  ast_log(LOG_WARNING, "Failed to parse URI '%s'\n", args->uri);
1158  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1159  args->ret = -1;
1160  return 0;
1161  }
1162 
1163  if (!strcmp(args->type, "scheme")) {
1164  ast_copy_pj_str(args->buf, pjsip_uri_get_scheme(uri), args->buflen);
1165  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1166  return 0;
1167  } else if (!strcmp(args->type, "display")) {
1168  ast_copy_pj_str(args->buf, &uri->display, args->buflen);
1169  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1170  return 0;
1171  }
1172 
1173  sip_uri = pjsip_uri_get_uri(uri);
1174  if (!sip_uri) {
1175  ast_log(LOG_ERROR, "Failed to get an URI object for '%s'\n", args->uri);
1176  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1177  args->ret = -1;
1178  return 0;
1179  }
1180 
1181  if (!strcmp(args->type, "user")) {
1182  ast_copy_pj_str(args->buf, &sip_uri->user, args->buflen);
1183  } else if (!strcmp(args->type, "passwd")) {
1184  ast_copy_pj_str(args->buf, &sip_uri->passwd, args->buflen);
1185  } else if (!strcmp(args->type, "host")) {
1186  ast_copy_pj_str(args->buf, &sip_uri->host, args->buflen);
1187  } else if (!strcmp(args->type, "port")) {
1188  snprintf(args->buf, args->buflen, "%d", sip_uri->port);
1189  } else if (!strcmp(args->type, "user_param")) {
1190  ast_copy_pj_str(args->buf, &sip_uri->user_param, args->buflen);
1191  } else if (!strcmp(args->type, "method_param")) {
1192  ast_copy_pj_str(args->buf, &sip_uri->method_param, args->buflen);
1193  } else if (!strcmp(args->type, "transport_param")) {
1194  ast_copy_pj_str(args->buf, &sip_uri->transport_param, args->buflen);
1195  } else if (!strcmp(args->type, "ttl_param")) {
1196  snprintf(args->buf, args->buflen, "%d", sip_uri->ttl_param);
1197  } else if (!strcmp(args->type, "lr_param")) {
1198  snprintf(args->buf, args->buflen, "%d", sip_uri->lr_param);
1199  } else if (!strcmp(args->type, "maddr_param")) {
1200  ast_copy_pj_str(args->buf, &sip_uri->maddr_param, args->buflen);
1201  } else {
1202  ast_log(AST_LOG_WARNING, "Unknown type part '%s' specified\n", args->type);
1203  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1204  args->ret = -1;
1205  return 0;
1206  }
1207 
1208  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1209 
1210  return 0;
1211 }
static int tmp()
Definition: bt_open.c:389
#define LOG_ERROR
Struct used to push PJSIP_PARSE_URI function arguments to task processor.
const char * args

References args, ast_copy_pj_str(), ast_log, AST_LOG_WARNING, ast_sip_get_pjsip_endpoint(), LOG_ERROR, LOG_WARNING, tmp(), and parse_uri_args::uri.

Referenced by pjsip_acf_parse_uri_read().

◆ pjsip_acf_channel_read()

int pjsip_acf_channel_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)

CHANNEL function read callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
bufOut buffer that should be populated with the data
lenSize of the buffer
Return values
0on success
-1on failure

Definition at line 932 of file pjsip/dialplan_functions.c.

933 {
934  struct pjsip_func_args func_args = { 0, };
935  struct ast_sip_channel_pvt *channel;
936  char *parse = ast_strdupa(data);
937 
939  AST_APP_ARG(param);
940  AST_APP_ARG(type);
941  AST_APP_ARG(field);
942  );
943 
944  if (!chan) {
945  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
946  return -1;
947  }
948 
949  /* Check for zero arguments */
950  if (ast_strlen_zero(parse)) {
951  ast_log(LOG_ERROR, "Cannot call %s without arguments\n", cmd);
952  return -1;
953  }
954 
956 
957  ast_channel_lock(chan);
958 
959  /* Sanity check */
960  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
961  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
962  ast_channel_unlock(chan);
963  return 0;
964  }
965 
966  channel = ast_channel_tech_pvt(chan);
967  if (!channel) {
968  ast_log(LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
969  ast_channel_unlock(chan);
970  return -1;
971  }
972 
973  if (!channel->session) {
974  ast_log(LOG_WARNING, "Channel %s has no session\n", ast_channel_name(chan));
975  ast_channel_unlock(chan);
976  return -1;
977  }
978 
979  func_args.session = ao2_bump(channel->session);
980  ast_channel_unlock(chan);
981 
982  memset(buf, 0, len);
983 
984  func_args.param = args.param;
985  func_args.type = args.type;
986  func_args.field = args.field;
987  func_args.buf = buf;
988  func_args.len = len;
989  if (ast_sip_push_task_wait_serializer(func_args.session->serializer, read_pjsip, &func_args)) {
990  ast_log(LOG_WARNING, "Unable to read properties of channel %s: failed to push task\n", ast_channel_name(chan));
991  ao2_ref(func_args.session, -1);
992  return -1;
993  }
994  ao2_ref(func_args.session, -1);
995 
996  return func_args.ret;
997 }
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1844
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
Definition: res_pjsip.c:2013
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with '\0'
static int read_pjsip(void *data)
Struct used to push function arguments to task processor.

References ao2_bump, ao2_ref, args, AST_APP_ARG, ast_channel_lock, ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log, ast_sip_push_task_wait_serializer(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), buf, func_args(), len(), LOG_ERROR, LOG_WARNING, parse(), read_pjsip(), ast_sip_channel_pvt::session, and type.

◆ pjsip_acf_dial_contacts_read()

int pjsip_acf_dial_contacts_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)

PJSIP_DIAL_CONTACTS function read callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
bufOut buffer that should be populated with the data
lenSize of the buffer
Return values
0on success
-1on failure

Definition at line 999 of file pjsip/dialplan_functions.c.

1000 {
1001  RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
1002  RAII_VAR(struct ast_str *, dial, NULL, ast_free_ptr);
1003  const char *aor_name;
1004  char *rest;
1005 
1007  AST_APP_ARG(endpoint_name);
1008  AST_APP_ARG(aor_name);
1009  AST_APP_ARG(request_user);
1010  );
1011 
1012  AST_STANDARD_APP_ARGS(args, data);
1013 
1014  if (ast_strlen_zero(args.endpoint_name)) {
1015  ast_log(LOG_WARNING, "An endpoint name must be specified when using the '%s' dialplan function\n", cmd);
1016  return -1;
1017  } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", args.endpoint_name))) {
1018  ast_log(LOG_WARNING, "Specified endpoint '%s' was not found\n", args.endpoint_name);
1019  return -1;
1020  }
1021 
1022  aor_name = S_OR(args.aor_name, endpoint->aors);
1023 
1024  if (ast_strlen_zero(aor_name)) {
1025  ast_log(LOG_WARNING, "No AOR has been provided and no AORs are configured on endpoint '%s'\n", args.endpoint_name);
1026  return -1;
1027  } else if (!(dial = ast_str_create(len))) {
1028  ast_log(LOG_WARNING, "Could not get enough buffer space for dialing contacts\n");
1029  return -1;
1030  } else if (!(rest = ast_strdupa(aor_name))) {
1031  ast_log(LOG_WARNING, "Could not duplicate provided AORs\n");
1032  return -1;
1033  }
1034 
1035  while ((aor_name = ast_strip(strsep(&rest, ",")))) {
1037  RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
1038  struct ao2_iterator it_contacts;
1039  struct ast_sip_contact *contact;
1040 
1041  if (!aor) {
1042  /* If the AOR provided is not found skip it, there may be more */
1043  continue;
1045  /* No contacts are available, skip it as well */
1046  continue;
1047  } else if (!ao2_container_count(contacts)) {
1048  /* We were given a container but no contacts are in it... */
1049  continue;
1050  }
1051 
1052  it_contacts = ao2_iterator_init(contacts, 0);
1053  for (; (contact = ao2_iterator_next(&it_contacts)); ao2_ref(contact, -1)) {
1054  ast_str_append(&dial, -1, "PJSIP/");
1055 
1056  if (!ast_strlen_zero(args.request_user)) {
1057  ast_str_append(&dial, -1, "%s@", args.request_user);
1058  }
1059  ast_str_append(&dial, -1, "%s/%s&", args.endpoint_name, contact->uri);
1060  }
1061  ao2_iterator_destroy(&it_contacts);
1062  }
1063 
1064  /* Trim the '&' at the end off */
1065  ast_str_truncate(dial, ast_str_strlen(dial) - 1);
1066 
1068 
1069  return 0;
1070 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
char * strsep(char **str, const char *delims)
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
Definition: location.c:147
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
@ AST_SIP_CONTACT_FILTER_REACHABLE
Return only reachable or unknown contacts.
Definition: res_pjsip.h:1089
struct ao2_container * ast_sip_location_retrieve_aor_contacts_filtered(const struct ast_sip_aor *aor, unsigned int flags)
Retrieve all contacts currently available for an AOR and filter based on flags.
Definition: location.c:252
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:764
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1117
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:640
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:711
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
A SIP address of record.
Definition: res_pjsip.h:376
Contact associated with an address of record.
Definition: res_pjsip.h:297
const ast_string_field aor
Definition: res_pjsip.h:319
An entity with which Asterisk communicates.
Definition: res_pjsip.h:854
Support for dynamic strings.
Definition: strings.h:604

References ao2_cleanup, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_sip_contact::aor, args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free_ptr(), ast_log, AST_SIP_CONTACT_FILTER_REACHABLE, ast_sip_get_sorcery(), ast_sip_location_retrieve_aor(), ast_sip_location_retrieve_aor_contacts_filtered(), ast_sorcery_retrieve_by_id(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_strlen(), ast_str_truncate(), ast_strdupa, ast_strip(), ast_strlen_zero(), buf, len(), LOG_WARNING, NULL, RAII_VAR, S_OR, and strsep().

◆ pjsip_acf_dtmf_mode_read()

int pjsip_acf_dtmf_mode_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)

PJSIP_DTMF_MODE function read callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
bufOut buffer that should be populated with the data
lenSize of the buffer
Return values
0on success
-1on failure

Definition at line 1445 of file pjsip/dialplan_functions.c.

1446 {
1447  struct ast_sip_channel_pvt *channel;
1448 
1449  if (!chan) {
1450  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1451  return -1;
1452  }
1453 
1454  ast_channel_lock(chan);
1455  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1456  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1457  ast_channel_unlock(chan);
1458  return -1;
1459  }
1460 
1461  channel = ast_channel_tech_pvt(chan);
1462 
1463  if (ast_sip_dtmf_to_str(channel->session->dtmf, buf, len) < 0) {
1464  ast_log(LOG_WARNING, "Unknown DTMF mode %d on PJSIP channel %s\n", channel->session->dtmf, ast_channel_name(chan));
1465  ast_channel_unlock(chan);
1466  return -1;
1467  }
1468 
1469  ast_channel_unlock(chan);
1470  return 0;
1471 }
int ast_sip_dtmf_to_str(const enum ast_sip_dtmf_mode dtmf, char *buf, size_t buf_len)
Convert the DTMF mode enum value into a string.
Definition: res_pjsip.c:2307
enum ast_sip_dtmf_mode dtmf

References ast_channel_lock, ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_log, ast_sip_dtmf_to_str(), buf, ast_sip_session::dtmf, len(), LOG_WARNING, ast_sip_channel_pvt::session, and type.

◆ pjsip_acf_dtmf_mode_write()

int pjsip_acf_dtmf_mode_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)

PJSIP_DTMF_MODE function write callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
valueValue to be set by the function
Return values
0on success
-1on failure

Definition at line 1546 of file pjsip/dialplan_functions.c.

1547 {
1548  struct ast_sip_channel_pvt *channel;
1549  struct ast_sip_session_media *media;
1550  int dsp_features = 0;
1551  int dtmf = -1;
1552  struct refresh_data rdata = {
1554  };
1555 
1556  if (!chan) {
1557  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1558  return -1;
1559  }
1560 
1561  ast_channel_lock(chan);
1562  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1563  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1564  ast_channel_unlock(chan);
1565  return -1;
1566  }
1567 
1568  channel = ast_channel_tech_pvt(chan);
1569  rdata.session = channel->session;
1570 
1571  dtmf = ast_sip_str_to_dtmf(value);
1572 
1573  if (dtmf == -1) {
1574  ast_log(LOG_WARNING, "Cannot set DTMF mode to '%s' on channel '%s' as value is invalid.\n", value,
1575  ast_channel_name(chan));
1576  ast_channel_unlock(chan);
1577  return -1;
1578  }
1579 
1580  if (channel->session->dtmf == dtmf) {
1581  /* DTMF mode unchanged, nothing to do! */
1582  ast_channel_unlock(chan);
1583  return 0;
1584  }
1585 
1586  channel->session->dtmf = dtmf;
1587 
1589 
1590  if (media && media->rtp) {
1591  if (channel->session->dtmf == AST_SIP_DTMF_RFC_4733) {
1594  } else if (channel->session->dtmf == AST_SIP_DTMF_INFO) {
1597  } else if (channel->session->dtmf == AST_SIP_DTMF_INBAND) {
1600  } else if (channel->session->dtmf == AST_SIP_DTMF_NONE) {
1603  } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO) {
1605  /* no RFC4733 negotiated, enable inband */
1607  }
1608  } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
1611  /* if inband, switch to INFO */
1613  }
1614  }
1615  }
1616 
1617  if (channel->session->dsp) {
1618  dsp_features = ast_dsp_get_features(channel->session->dsp);
1619  }
1620  if (channel->session->dtmf == AST_SIP_DTMF_INBAND ||
1621  channel->session->dtmf == AST_SIP_DTMF_AUTO) {
1622  dsp_features |= DSP_FEATURE_DIGIT_DETECT;
1623  } else {
1624  dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
1625  }
1626  if (dsp_features) {
1627  if (!channel->session->dsp) {
1628  if (!(channel->session->dsp = ast_dsp_new())) {
1629  ast_channel_unlock(chan);
1630  return 0;
1631  }
1632  }
1633  ast_dsp_set_features(channel->session->dsp, dsp_features);
1634  } else if (channel->session->dsp) {
1635  ast_dsp_free(channel->session->dsp);
1636  channel->session->dsp = NULL;
1637  }
1638 
1639  ast_channel_unlock(chan);
1640 
1642 }
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1773
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1748
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1767
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1758
static int dtmf_mode_refresh_cb(void *obj)
@ AST_SIP_DTMF_NONE
Definition: res_pjsip.h:429
@ AST_SIP_DTMF_AUTO_INFO
Definition: res_pjsip.h:440
@ AST_SIP_DTMF_AUTO
Definition: res_pjsip.h:438
@ AST_SIP_DTMF_INBAND
Definition: res_pjsip.h:434
@ AST_SIP_DTMF_INFO
Definition: res_pjsip.h:436
@ AST_SIP_DTMF_RFC_4733
Definition: res_pjsip.h:432
int ast_sip_str_to_dtmf(const char *dtmf_mode)
Convert the DTMF mode name into an enum.
Definition: res_pjsip.c:2336
@ AST_SIP_SESSION_REFRESH_METHOD_INVITE
Definition: res_pjsip.h:507
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2129
@ AST_RTP_DTMF_MODE_RFC2833
Definition: rtp_engine.h:152
@ AST_RTP_DTMF_MODE_INBAND
Definition: rtp_engine.h:154
@ AST_RTP_DTMF_MODE_NONE
Definition: rtp_engine.h:150
int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
Set the DTMF mode that should be used.
Definition: rtp_engine.c:2115
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
@ AST_RTP_PROPERTY_DTMF
Definition: rtp_engine.h:117
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
struct ast_sip_session_media_state * active_media_state
struct ast_dsp * dsp
struct ast_taskprocessor * serializer
int value
Definition: syslog.c:37

References ast_sip_session::active_media_state, ast_channel_lock, ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_dsp_free(), ast_dsp_get_features(), ast_dsp_new(), ast_dsp_set_features(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_NONE, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_get(), ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_INFO, AST_SIP_DTMF_NONE, AST_SIP_DTMF_RFC_4733, ast_sip_push_task_wait_serializer(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, ast_sip_str_to_dtmf(), ast_sip_session_media_state::default_session, ast_sip_session::dsp, DSP_FEATURE_DIGIT_DETECT, ast_sip_session::dtmf, dtmf_mode_refresh_cb(), LOG_WARNING, refresh_data::method, NULL, ast_sip_session_media::rtp, ast_sip_session::serializer, refresh_data::session, ast_sip_channel_pvt::session, type, and value.

◆ pjsip_acf_media_offer_read()

int pjsip_acf_media_offer_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)

PJSIP_MEDIA_OFFER function read callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
bufOut buffer that should be populated with the data
lenSize of the buffer
Return values
0on success
-1on failure

Definition at line 1388 of file pjsip/dialplan_functions.c.

1389 {
1390  struct ast_sip_channel_pvt *channel;
1391 
1392  if (!chan) {
1393  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1394  return -1;
1395  }
1396 
1397  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1398  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1399  return -1;
1400  }
1401 
1402  channel = ast_channel_tech_pvt(chan);
1403 
1404  if (!strcmp(data, "audio")) {
1406  } else if (!strcmp(data, "video")) {
1408  } else {
1409  /* Ensure that the buffer is empty */
1410  buf[0] = '\0';
1411  }
1412 
1413  return 0;
1414 }
static int media_offer_read_av(struct ast_sip_session *session, char *buf, size_t len, enum ast_media_type media_type)

References ast_channel_tech(), ast_channel_tech_pvt(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, buf, len(), LOG_WARNING, media_offer_read_av(), ast_sip_channel_pvt::session, and type.

◆ pjsip_acf_media_offer_write()

int pjsip_acf_media_offer_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)

PJSIP_MEDIA_OFFER function write callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
valueValue to be set by the function
Return values
0on success
-1on failure

Definition at line 1416 of file pjsip/dialplan_functions.c.

1417 {
1418  struct ast_sip_channel_pvt *channel;
1419  struct media_offer_data mdata = {
1420  .value = value
1421  };
1422 
1423  if (!chan) {
1424  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1425  return -1;
1426  }
1427 
1428  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1429  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1430  return -1;
1431  }
1432 
1433  channel = ast_channel_tech_pvt(chan);
1434  mdata.session = channel->session;
1435 
1436  if (!strcmp(data, "audio")) {
1438  } else if (!strcmp(data, "video")) {
1440  }
1441 
1443 }
static int media_offer_write_av(void *obj)

References ast_channel_tech(), ast_channel_tech_pvt(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, ast_sip_push_task_wait_serializer(), LOG_WARNING, media_offer_write_av(), media_offer_data::media_type, ast_sip_session::serializer, media_offer_data::session, ast_sip_channel_pvt::session, type, media_offer_data::value, and value.

◆ pjsip_acf_moh_passthrough_read()

int pjsip_acf_moh_passthrough_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)

PJSIP_MOH_PASSTHROUGH function read callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
bufOut buffer that should be populated with the data
lenSize of the buffer
Return values
0on success
-1on failure

Definition at line 1473 of file pjsip/dialplan_functions.c.

1474 {
1475  struct ast_sip_channel_pvt *channel;
1476 
1477  if (!chan) {
1478  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1479  return -1;
1480  }
1481 
1482  if (len < 3) {
1483  ast_log(LOG_WARNING, "%s: buffer too small\n", cmd);
1484  return -1;
1485  }
1486 
1487  ast_channel_lock(chan);
1488  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1489  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1490  ast_channel_unlock(chan);
1491  return -1;
1492  }
1493 
1494  channel = ast_channel_tech_pvt(chan);
1495  strncpy(buf, AST_YESNO(channel->session->moh_passthrough), len);
1496 
1497  ast_channel_unlock(chan);
1498  return 0;
1499 }
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:143
unsigned int moh_passthrough

References ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_log, AST_YESNO, buf, len(), LOG_WARNING, ast_sip_session::moh_passthrough, ast_sip_channel_pvt::session, and type.

◆ pjsip_acf_moh_passthrough_write()

int pjsip_acf_moh_passthrough_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)

PJSIP_MOH_PASSTHROUGH function write callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
valueValue to be set by the function
Return values
0on success
-1on failure

Definition at line 1644 of file pjsip/dialplan_functions.c.

1645 {
1646  struct ast_sip_channel_pvt *channel;
1647 
1648  if (!chan) {
1649  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1650  return -1;
1651  }
1652 
1653  ast_channel_lock(chan);
1654  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1655  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1656  ast_channel_unlock(chan);
1657  return -1;
1658  }
1659 
1660  channel = ast_channel_tech_pvt(chan);
1661  channel->session->moh_passthrough = ast_true(value);
1662 
1663  ast_channel_unlock(chan);
1664 
1665  return 0;
1666 }
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: main/utils.c:2097

References ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_log, ast_true(), LOG_WARNING, ast_sip_session::moh_passthrough, ast_sip_channel_pvt::session, type, and value.

◆ pjsip_acf_parse_uri_read()

int pjsip_acf_parse_uri_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)

PJSIP_PARSE_URI function read callback.

Parameters
chanThe channel the function is called on
cmdThe name of the function
dataArguments passed to the function
bufOut buffer that should be populated with the data
lenSize of the buffer
Return values
0on success
-1on failure

Definition at line 1213 of file pjsip/dialplan_functions.c.

1214 {
1215  struct parse_uri_args func_args = { 0, };
1216 
1218  AST_APP_ARG(uri_str);
1219  AST_APP_ARG(type);
1220  );
1221 
1222  AST_STANDARD_APP_ARGS(args, data);
1223 
1224  if (ast_strlen_zero(args.uri_str)) {
1225  ast_log(LOG_WARNING, "An URI must be specified when using the '%s' dialplan function\n", cmd);
1226  return -1;
1227  }
1228 
1229  if (ast_strlen_zero(args.type)) {
1230  ast_log(LOG_WARNING, "A type part of the URI must be specified when using the '%s' dialplan function\n", cmd);
1231  return -1;
1232  }
1233 
1234  memset(buf, 0, buflen);
1235 
1236  func_args.uri = args.uri_str;
1237  func_args.type = args.type;
1238  func_args.buf = buf;
1239  func_args.buflen = buflen;
1241  ast_log(LOG_WARNING, "Unable to parse URI: failed to push task\n");
1242  return -1;
1243  }
1244 
1245  return func_args.ret;
1246 }
static int parse_uri_cb(void *data)

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, ast_sip_push_task_wait_serializer(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), buf, parse_uri_args::buflen, func_args(), LOG_WARNING, NULL, parse_uri_cb(), and type.

◆ pjsip_acf_session_refresh_write()

int pjsip_acf_session_refresh_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)

PJSIP_SEND_SESSION_REFRESH function write callback.

Parameters
chanThe channel the function is called on
cmdthe Name of the function
dataArguments passed to the function
valueValue to be set by the function
Return values
0on success
-1on failure

Definition at line 1687 of file pjsip/dialplan_functions.c.

1688 {
1689  struct ast_sip_channel_pvt *channel;
1690  struct refresh_data rdata = {
1692  };
1693 
1694  if (!chan) {
1695  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1696  return -1;
1697  }
1698 
1699  if (ast_channel_state(chan) != AST_STATE_UP) {
1700  ast_log(LOG_WARNING, "'%s' not allowed on unanswered channel '%s'.\n", cmd, ast_channel_name(chan));
1701  return -1;
1702  }
1703 
1704  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1705  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1706  return -1;
1707  }
1708 
1709  channel = ast_channel_tech_pvt(chan);
1710  rdata.session = channel->session;
1711 
1712  if (!strcmp(value, "invite")) {
1714  } else if (!strcmp(value, "update")) {
1716  }
1717 
1719 }
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
static int refresh_write_cb(void *obj)
@ AST_SIP_SESSION_REFRESH_METHOD_UPDATE
Definition: res_pjsip.h:509

References ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_log, ast_sip_push_task_wait_serializer(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, AST_SIP_SESSION_REFRESH_METHOD_UPDATE, AST_STATE_UP, LOG_WARNING, refresh_data::method, refresh_write_cb(), ast_sip_session::serializer, refresh_data::session, ast_sip_channel_pvt::session, type, and value.

◆ print_escaped_uri()

static int print_escaped_uri ( struct ast_channel chan,
const char *  type,
pjsip_uri_context_e  context,
const void *  uri,
char *  buf,
size_t  size 
)
static

Definition at line 752 of file pjsip/dialplan_functions.c.

754 {
755  int res;
756  char *buf_copy;
757 
758  res = pjsip_uri_print(context, uri, buf, size);
759  if (res < 0) {
760  ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n",
761  ast_channel_name(chan), type, (int) size);
762 
763  /* Empty buffer that likely is not terminated. */
764  buf[0] = '\0';
765  return -1;
766  }
767 
768  buf_copy = ast_strdupa(buf);
769  ast_escape_quoted(buf_copy, buf, size);
770  return 0;
771 }
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120

References ast_channel_name(), ast_escape_quoted(), ast_log, ast_strdupa, buf, context, LOG_ERROR, and type.

Referenced by channel_read_pjsip().

◆ read_pjsip()

static int read_pjsip ( void *  data)
static

Definition at line 878 of file pjsip/dialplan_functions.c.

879 {
880  struct pjsip_func_args *func_args = data;
881 
882  if (!strcmp(func_args->param, "rtp")) {
883  if (!func_args->session->channel) {
884  func_args->ret = -1;
885  return 0;
886  }
887  func_args->ret = channel_read_rtp(func_args->session->channel, func_args->type,
888  func_args->field, func_args->buf,
889  func_args->len);
890  } else if (!strcmp(func_args->param, "rtcp")) {
891  if (!func_args->session->channel) {
892  func_args->ret = -1;
893  return 0;
894  }
895  func_args->ret = channel_read_rtcp(func_args->session->channel, func_args->type,
896  func_args->field, func_args->buf,
897  func_args->len);
898  } else if (!strcmp(func_args->param, "endpoint")) {
899  if (!func_args->session->endpoint) {
900  ast_log(AST_LOG_WARNING, "Channel %s has no endpoint!\n", func_args->session->channel ?
901  ast_channel_name(func_args->session->channel) : "<unknown>");
902  func_args->ret = -1;
903  return 0;
904  }
905  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->endpoint));
906  } else if (!strcmp(func_args->param, "contact")) {
907  if (!func_args->session->contact) {
908  return 0;
909  }
910  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->contact));
911  } else if (!strcmp(func_args->param, "aor")) {
912  if (!func_args->session->aor) {
913  return 0;
914  }
915  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->aor));
916  } else if (!strcmp(func_args->param, "pjsip")) {
917  if (!func_args->session->channel) {
918  func_args->ret = -1;
919  return 0;
920  }
921  func_args->ret = channel_read_pjsip(func_args->session->channel, func_args->type,
922  func_args->field, func_args->buf,
923  func_args->len);
924  } else {
925  func_args->ret = -1;
926  }
927 
928  return 0;
929 }
static int channel_read_rtp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
static int channel_read_pjsip(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
static int channel_read_rtcp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312

References ast_channel_name(), ast_log, AST_LOG_WARNING, ast_sorcery_object_get_id(), channel_read_pjsip(), channel_read_rtcp(), channel_read_rtp(), and func_args().

Referenced by pjsip_acf_channel_read().

◆ refresh_write_cb()

static int refresh_write_cb ( void *  obj)
static

Definition at line 1668 of file pjsip/dialplan_functions.c.

1669 {
1670  struct refresh_data *data = obj;
1671  struct session_refresh_state *state;
1672 
1674  if (!state) {
1675  return -1;
1676  }
1677 
1679  sip_session_response_cb, data->method, 1, state->media_state);
1680 
1681  state->media_state = NULL;
1682  ast_sip_session_remove_datastore(data->session, "pjsip_session_refresh");
1683 
1684  return 0;
1685 }
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.

References ast_sip_session_refresh(), ast_sip_session_remove_datastore(), refresh_data::method, NULL, refresh_data::session, session_refresh_state_get_or_alloc(), sip_session_response_cb(), and state.

Referenced by pjsip_acf_session_refresh_write().

◆ session_refresh_state_destroy()

static void session_refresh_state_destroy ( void *  obj)
static

Destructor for session refresh information.

Definition at line 1079 of file pjsip/dialplan_functions.c.

1080 {
1081  struct session_refresh_state *state = obj;
1082 
1084  ast_free(obj);
1085 }
#define ast_free(a)
Definition: astmm.h:180
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.

◆ session_refresh_state_get_or_alloc()

static struct session_refresh_state* session_refresh_state_get_or_alloc ( struct ast_sip_session session)
static

Helper function which retrieves or allocates a session refresh state information datastore.

Definition at line 1094 of file pjsip/dialplan_functions.c.

1095 {
1096  RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "pjsip_session_refresh"), ao2_cleanup);
1097  struct session_refresh_state *state;
1098 
1099  /* While the datastore refcount is decremented this is operating in the serializer so it will remain valid regardless */
1100  if (datastore) {
1101  return datastore->data;
1102  }
1103 
1104  if (!(datastore = ast_sip_session_alloc_datastore(&session_refresh_datastore, "pjsip_session_refresh"))
1105  || !(datastore->data = ast_calloc(1, sizeof(struct session_refresh_state)))
1106  || ast_sip_session_add_datastore(session, datastore)) {
1107  return NULL;
1108  }
1109 
1110  state = datastore->data;
1111  state->media_state = ast_sip_session_media_state_alloc();
1112  if (!state->media_state) {
1113  ast_sip_session_remove_datastore(session, "pjsip_session_refresh");
1114  return NULL;
1115  }
1116  state->media_state->topology = ast_stream_topology_clone(session->endpoint->media.topology);
1117  if (!state->media_state->topology) {
1118  ast_sip_session_remove_datastore(session, "pjsip_session_refresh");
1119  return NULL;
1120  }
1121 
1122  datastore->data = state;
1123 
1124  return state;
1125 }
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static const struct ast_datastore_info session_refresh_datastore
Datastore for attaching session refresh state information.
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.

References ao2_cleanup, ast_calloc, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_datastore(), ast_sip_session_media_state_alloc(), ast_sip_session_remove_datastore(), ast_stream_topology_clone(), NULL, RAII_VAR, session, session_refresh_datastore, and state.

Referenced by media_offer_read_av(), media_offer_write_av(), and refresh_write_cb().

◆ sip_session_response_cb()

static int sip_session_response_cb ( struct ast_sip_session session,
pjsip_rx_data *  rdata 
)
static

Definition at line 1506 of file pjsip/dialplan_functions.c.

1507 {
1508  struct ast_format *fmt;
1509 
1510  if (!session->channel) {
1511  /* Egads! */
1512  return 0;
1513  }
1514 
1516  if (!fmt) {
1517  /* No format? That's weird. */
1518  return 0;
1519  }
1520  ast_channel_set_writeformat(session->channel, fmt);
1521  ast_channel_set_rawwriteformat(session->channel, fmt);
1522  ast_channel_set_readformat(session->channel, fmt);
1523  ast_channel_set_rawreadformat(session->channel, fmt);
1524  ao2_ref(fmt, -1);
1525 
1526  return 0;
1527 }
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition: format_cap.c:417

References ao2_ref, ast_channel_nativeformats(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_format_cap_get_best_by_type(), AST_MEDIA_TYPE_AUDIO, and session.

Referenced by dtmf_mode_refresh_cb(), and refresh_write_cb().

Variable Documentation

◆ session_refresh_datastore

const struct ast_datastore_info session_refresh_datastore
static
Initial value:
= {
.type = "pjsip_session_refresh",
}
static void session_refresh_state_destroy(void *obj)
Destructor for session refresh information.

Datastore for attaching session refresh state information.

Definition at line 1079 of file pjsip/dialplan_functions.c.

Referenced by session_refresh_state_get_or_alloc().

◆ t38state_to_string

const char* t38state_to_string[T38_MAX_ENUM]
static

String representations of the T.38 state enum.

Definition at line 557 of file pjsip/dialplan_functions.c.

Referenced by channel_read_pjsip().