Asterisk - The Open Source Telephony Project  18.5.0
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 <[email protected]> 
Matt Jordan <[email protected]> 

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 760 of file pjsip/dialplan_functions.c.

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, ast_sip_session::inv_session, transport_info_data::local_addr, LOG_WARNING, NULL, pool, print_escaped_uri(), RAII_VAR, transport_info_data::remote_addr, ast_sip_session::request_uri, ast_sip_channel_pvt::session, ast_sip_session::t38state, and t38state_to_string.

Referenced by read_pjsip().

761 {
763  char *buf_copy;
764  pjsip_dialog *dlg;
765  int res = 0;
766 
767  if (!channel) {
768  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
769  return -1;
770  }
771 
772  dlg = channel->session->inv_session->dlg;
773 
774  if (ast_strlen_zero(type)) {
775  ast_log(LOG_WARNING, "You must supply a type field for 'pjsip' information\n");
776  return -1;
777  } else if (!strcmp(type, "call-id")) {
778  snprintf(buf, buflen, "%.*s", (int) pj_strlen(&dlg->call_id->id), pj_strbuf(&dlg->call_id->id));
779  } else if (!strcmp(type, "secure")) {
780 #ifdef HAVE_PJSIP_GET_DEST_INFO
781  pjsip_host_info dest;
782  pj_pool_t *pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "secure-check", 128, 128);
783  pjsip_get_dest_info(dlg->target, NULL, pool, &dest);
784  snprintf(buf, buflen, "%d", dest.flag & PJSIP_TRANSPORT_SECURE ? 1 : 0);
785  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
786 #else
787  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");
788  return -1;
789 #endif
790  } else if (!strcmp(type, "target_uri")) {
791  res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf,
792  buflen);
793  } else if (!strcmp(type, "local_uri")) {
794  res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri,
795  buf, buflen);
796  } else if (!strcmp(type, "local_tag")) {
797  ast_copy_pj_str(buf, &dlg->local.info->tag, buflen);
798  buf_copy = ast_strdupa(buf);
799  ast_escape_quoted(buf_copy, buf, buflen);
800  } else if (!strcmp(type, "remote_uri")) {
801  res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR,
802  dlg->remote.info->uri, buf, buflen);
803  } else if (!strcmp(type, "remote_tag")) {
804  ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen);
805  buf_copy = ast_strdupa(buf);
806  ast_escape_quoted(buf_copy, buf, buflen);
807  } else if (!strcmp(type, "request_uri")) {
808  if (channel->session->request_uri) {
809  res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI,
810  channel->session->request_uri, buf, buflen);
811  }
812  } else if (!strcmp(type, "t38state")) {
814  } else if (!strcmp(type, "local_addr")) {
815  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
816  struct transport_info_data *transport_data;
817 
818  datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
819  if (!datastore) {
820  ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
821  return -1;
822  }
823  transport_data = datastore->data;
824 
825  if (pj_sockaddr_has_addr(&transport_data->local_addr)) {
826  pj_sockaddr_print(&transport_data->local_addr, buf, buflen, 3);
827  }
828  } else if (!strcmp(type, "remote_addr")) {
829  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
830  struct transport_info_data *transport_data;
831 
832  datastore = ast_sip_session_get_datastore(channel->session, "transport_info");
833  if (!datastore) {
834  ast_log(AST_LOG_WARNING, "No transport information for channel %s\n", ast_channel_name(chan));
835  return -1;
836  }
837  transport_data = datastore->data;
838 
839  if (pj_sockaddr_has_addr(&transport_data->remote_addr)) {
840  pj_sockaddr_print(&transport_data->remote_addr, buf, buflen, 3);
841  }
842  } else {
843  ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'pjsip' information\n", type);
844  return -1;
845  }
846 
847  return res;
848 }
static const char type[]
Definition: chan_ooh323.c:109
enum ast_sip_session_t38state t38state
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)
pj_sockaddr local_addr
Our address that received the request.
Definition: chan_pjsip.h:34
void * ast_channel_tech_pvt(const struct ast_channel *chan)
pjsip_uri * request_uri
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define AST_LOG_WARNING
Definition: logger.h:279
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
Structure for a data store object.
Definition: datastore.h:68
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:5240
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
Transport information stored in transport_info datastore.
Definition: chan_pjsip.h:30
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
pj_sockaddr remote_addr
The address that sent the request.
Definition: chan_pjsip.h:32
static const char * t38state_to_string[T38_MAX_ENUM]
String representations of the T.38 state enum.
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:635
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3718
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)

◆ 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 619 of file pjsip/dialplan_functions.c.

References ast_sip_session::active_media_state, 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, ast_sip_session_media_state::default_session, 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, session, ast_sip_channel_pvt::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().

620 {
622  struct ast_sip_session *session;
623  struct ast_sip_session_media *media;
624 
625  if (!channel) {
626  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
627  return -1;
628  }
629 
630  session = channel->session;
631  if (!session) {
632  ast_log(AST_LOG_WARNING, "Channel %s has no session!\n", ast_channel_name(chan));
633  return -1;
634  }
635 
636  if (ast_strlen_zero(type)) {
637  ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtcp' information\n");
638  return -1;
639  }
640 
641  if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
643  } else if (!strcmp(field, "video")) {
645  } else {
646  ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtcp' information\n", field);
647  return -1;
648  }
649 
650  if (!media || !media->rtp) {
651  ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
652  ast_channel_name(chan), S_OR(field, "audio"));
653  return -1;
654  }
655 
656  if (!strncasecmp(type, "all", 3)) {
658 
659  if (!strcasecmp(type, "all_jitter")) {
661  } else if (!strcasecmp(type, "all_rtt")) {
663  } else if (!strcasecmp(type, "all_loss")) {
665  }
666 
667  if (!ast_rtp_instance_get_quality(media->rtp, stat_field, buf, buflen)) {
668  ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
669  return -1;
670  }
671  } else {
672  struct ast_rtp_instance_stats stats;
673  int i;
674  struct {
675  const char *name;
676  enum { INT, DBL } type;
677  union {
678  unsigned int *i4;
679  double *d8;
680  };
681  } lookup[] = {
682  { "txcount", INT, { .i4 = &stats.txcount, }, },
683  { "rxcount", INT, { .i4 = &stats.rxcount, }, },
684  { "txjitter", DBL, { .d8 = &stats.txjitter, }, },
685  { "rxjitter", DBL, { .d8 = &stats.rxjitter, }, },
686  { "remote_maxjitter", DBL, { .d8 = &stats.remote_maxjitter, }, },
687  { "remote_minjitter", DBL, { .d8 = &stats.remote_minjitter, }, },
688  { "remote_normdevjitter", DBL, { .d8 = &stats.remote_normdevjitter, }, },
689  { "remote_stdevjitter", DBL, { .d8 = &stats.remote_stdevjitter, }, },
690  { "local_maxjitter", DBL, { .d8 = &stats.local_maxjitter, }, },
691  { "local_minjitter", DBL, { .d8 = &stats.local_minjitter, }, },
692  { "local_normdevjitter", DBL, { .d8 = &stats.local_normdevjitter, }, },
693  { "local_stdevjitter", DBL, { .d8 = &stats.local_stdevjitter, }, },
694  { "txploss", INT, { .i4 = &stats.txploss, }, },
695  { "rxploss", INT, { .i4 = &stats.rxploss, }, },
696  { "remote_maxrxploss", DBL, { .d8 = &stats.remote_maxrxploss, }, },
697  { "remote_minrxploss", DBL, { .d8 = &stats.remote_minrxploss, }, },
698  { "remote_normdevrxploss", DBL, { .d8 = &stats.remote_normdevrxploss, }, },
699  { "remote_stdevrxploss", DBL, { .d8 = &stats.remote_stdevrxploss, }, },
700  { "local_maxrxploss", DBL, { .d8 = &stats.local_maxrxploss, }, },
701  { "local_minrxploss", DBL, { .d8 = &stats.local_minrxploss, }, },
702  { "local_normdevrxploss", DBL, { .d8 = &stats.local_normdevrxploss, }, },
703  { "local_stdevrxploss", DBL, { .d8 = &stats.local_stdevrxploss, }, },
704  { "rtt", DBL, { .d8 = &stats.rtt, }, },
705  { "maxrtt", DBL, { .d8 = &stats.maxrtt, }, },
706  { "minrtt", DBL, { .d8 = &stats.minrtt, }, },
707  { "normdevrtt", DBL, { .d8 = &stats.normdevrtt, }, },
708  { "stdevrtt", DBL, { .d8 = &stats.stdevrtt, }, },
709  { "local_ssrc", INT, { .i4 = &stats.local_ssrc, }, },
710  { "remote_ssrc", INT, { .i4 = &stats.remote_ssrc, }, },
711  { NULL, },
712  };
713 
715  ast_log(AST_LOG_WARNING, "Unable to retrieve 'rtcp' statistics for %s\n", ast_channel_name(chan));
716  return -1;
717  }
718 
719  for (i = 0; !ast_strlen_zero(lookup[i].name); i++) {
720  if (!strcasecmp(type, lookup[i].name)) {
721  if (lookup[i].type == INT) {
722  snprintf(buf, buflen, "%u", *lookup[i].i4);
723  } else {
724  snprintf(buf, buflen, "%f", *lookup[i].d8);
725  }
726  return 0;
727  }
728  }
729  ast_log(AST_LOG_WARNING, "Unrecognized argument '%s' for 'rtcp' information\n", type);
730  return -1;
731  }
732 
733  return 0;
734 }
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
void * ast_channel_tech_pvt(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_LOG_WARNING
Definition: logger.h:279
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define NULL
Definition: resample.c:96
A structure describing a SIP session.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sip_session_media_state * active_media_state
#define ast_log
Definition: astobj2.c:42
static struct ast_mansession session
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
static const char name[]
Definition: cdr_mysql.c:74
A structure containing SIP session media information.
ast_rtp_instance_stat_field
Definition: rtp_engine.h:168
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)

◆ 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 552 of file pjsip/dialplan_functions.c.

References ast_sip_session::active_media_state, 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, ast_sip_session_media_state::default_session, ast_sip_session_media::direct_media_addr, ast_sip_session_media::remotely_held, ast_sip_session_media::rtp, S_OR, session, ast_sip_channel_pvt::session, and ast_sip_session_media::srtp.

Referenced by read_pjsip().

553 {
555  struct ast_sip_session *session;
556  struct ast_sip_session_media *media;
557  struct ast_sockaddr addr;
558 
559  if (!channel) {
560  ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
561  return -1;
562  }
563 
564  session = channel->session;
565  if (!session) {
566  ast_log(AST_LOG_WARNING, "Channel %s has no session!\n", ast_channel_name(chan));
567  return -1;
568  }
569 
570  if (ast_strlen_zero(type)) {
571  ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtp' information\n");
572  return -1;
573  }
574 
575  if (ast_strlen_zero(field) || !strcmp(field, "audio")) {
577  } else if (!strcmp(field, "video")) {
579  } else {
580  ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtp' information\n", field);
581  return -1;
582  }
583 
584  if (!media || !media->rtp) {
585  ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n",
586  ast_channel_name(chan), S_OR(field, "audio"));
587  return -1;
588  }
589 
590  if (!strcmp(type, "src")) {
592  ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
593  } else if (!strcmp(type, "dest")) {
595  ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen);
596  } else if (!strcmp(type, "direct")) {
598  } else if (!strcmp(type, "secure")) {
599  if (media->srtp) {
600  struct ast_sdp_srtp *srtp = media->srtp;
602  snprintf(buf, buflen, "%d", flag ? 1 : 0);
603  } else {
604  snprintf(buf, buflen, "%d", 0);
605  }
606  } else if (!strcmp(type, "hold")) {
607  snprintf(buf, buflen, "%d", media->remotely_held ? 1 : 0);
608  } else {
609  ast_log(AST_LOG_WARNING, "Unknown type field '%s' specified for 'rtp' information\n", type);
610  return -1;
611  }
612 
613  return 0;
614 }
static const char type[]
Definition: chan_ooh323.c:109
structure for secure RTP audio
Definition: sdp_srtp.h:37
struct ast_sockaddr direct_media_addr
Direct media address.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_LOG_WARNING
Definition: logger.h:279
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
Socket address structure.
Definition: netsock2.h:97
A structure describing a SIP session.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sip_session_media_state * active_media_state
#define ast_log
Definition: astobj2.c:42
static struct ast_mansession session
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:44
struct ast_sdp_srtp * srtp
Holds SRTP information.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
unsigned int remotely_held
Stream is on hold by remote side.
long int flag
Definition: f2c.h:83
A structure containing SIP session media information.
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
#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

◆ dtmf_mode_refresh_cb()

static int dtmf_mode_refresh_cb ( void *  obj)
static

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

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().

1514 {
1515  struct refresh_data *data = obj;
1516 
1517  if (data->session->inv_session->state == PJSIP_INV_STATE_CONFIRMED) {
1518  ast_debug(3, "Changing DTMF mode on channel %s after OFFER/ANSWER completion. Sending session refresh\n", ast_channel_name(data->session->channel));
1519 
1521  sip_session_response_cb, data->method, 1, NULL);
1522  } else if (data->session->inv_session->state == PJSIP_INV_STATE_INCOMING) {
1523  ast_debug(3, "Changing DTMF mode on channel %s during OFFER/ANSWER exchange. Updating SDP answer\n", ast_channel_name(data->session->channel));
1525  }
1526 
1527  return 0;
1528 }
static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
enum ast_sip_session_refresh_method method
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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
const char * ast_channel_name(const struct ast_channel *chan)
int ast_sip_session_regenerate_answer(struct ast_sip_session *session, ast_sip_session_sdp_creation_cb on_sdp_creation)
Regenerate SDP Answer.

◆ 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 1232 of file pjsip/dialplan_functions.c.

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(), ast_sip_session::endpoint, ast_sip_session::inv_session, ast_sip_endpoint::media, session_refresh_state::media_state, NULL, ast_sip_session::pending_media_state, session_refresh_state_get_or_alloc(), state, ast_sip_session_media_state::topology, and ast_sip_endpoint_media_configuration::topology.

Referenced by pjsip_acf_media_offer_read().

1234 {
1235  struct ast_stream_topology *topology;
1236  int idx;
1237  struct ast_stream *stream = NULL;
1238  const struct ast_format_cap *caps;
1239  size_t accum = 0;
1240 
1241  if (session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
1242  struct session_refresh_state *state;
1243 
1244  /* As we've already answered we need to store our media state until we are ready to send it */
1245  state = session_refresh_state_get_or_alloc(session);
1246  if (!state) {
1247  return -1;
1248  }
1249  topology = state->media_state->topology;
1250  } else {
1251  /* The session is not yet up so we are initially answering or offering */
1252  if (!session->pending_media_state->topology) {
1254  if (!session->pending_media_state->topology) {
1255  return -1;
1256  }
1257  }
1258  topology = session->pending_media_state->topology;
1259  }
1260 
1261  /* Find the first suitable stream */
1262  for (idx = 0; idx < ast_stream_topology_get_count(topology); ++idx) {
1263  stream = ast_stream_topology_get_stream(topology, idx);
1264 
1265  if (ast_stream_get_type(stream) != media_type ||
1267  stream = NULL;
1268  continue;
1269  }
1270 
1271  break;
1272  }
1273 
1274  /* If no suitable stream then exit early */
1275  if (!stream) {
1276  buf[0] = '\0';
1277  return 0;
1278  }
1279 
1280  caps = ast_stream_get_formats(stream);
1281 
1282  /* Note: buf is not terminated while the string is being built. */
1283  for (idx = 0; idx < ast_format_cap_count(caps); ++idx) {
1284  struct ast_format *fmt;
1285  size_t size;
1286 
1287  fmt = ast_format_cap_get_format(caps, idx);
1288 
1289  /* Add one for a comma or terminator */
1290  size = strlen(ast_format_get_name(fmt)) + 1;
1291  if (len < size) {
1292  ao2_ref(fmt, -1);
1293  break;
1294  }
1295 
1296  /* Append the format name */
1297  strcpy(buf + accum, ast_format_get_name(fmt));/* Safe */
1298  ao2_ref(fmt, -1);
1299 
1300  accum += size;
1301  len -= size;
1302 
1303  /* The last comma on the built string will be set to the terminator. */
1304  buf[accum - 1] = ',';
1305  }
1306 
1307  /* Remove the trailing comma or terminate an empty buffer. */
1308  buf[accum ? accum - 1 : 0] = '\0';
1309  return 0;
1310 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
struct ast_sip_endpoint * endpoint
struct ast_sip_session_media_state * pending_media_state
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream...
Definition: sip.h:489
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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_sip_session_media_state * media_state
Created proposed media state.
Set when the stream has been removed/declined.
Definition: stream.h:78
Session refresh state information.
Definition of a media format.
Definition: format.c:43
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
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
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
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
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.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
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
struct ast_stream_topology * topology
Definition: res_pjsip.h:772
struct ast_stream_topology * topology
The media stream topology.
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
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373

◆ media_offer_write_av()

static int media_offer_write_av ( void *  obj)
static

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

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, session_refresh_state::media_state, media_offer_data::media_type, ast_sip_session::pending_media_state, media_offer_data::session, session_refresh_state_get_or_alloc(), state, ast_sip_session_media_state::topology, ast_sip_endpoint_media_configuration::topology, and media_offer_data::value.

Referenced by pjsip_acf_media_offer_write().

1319 {
1320  struct media_offer_data *data = obj;
1321  struct ast_stream_topology *topology;
1322  struct ast_stream *stream;
1323  struct ast_format_cap *caps;
1324 
1325  if (data->session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
1326  struct session_refresh_state *state;
1327 
1328  /* As we've already answered we need to store our media state until we are ready to send it */
1330  if (!state) {
1331  return -1;
1332  }
1333  topology = state->media_state->topology;
1334  } else {
1335  /* The session is not yet up so we are initially answering or offering */
1336  if (!data->session->pending_media_state->topology) {
1338  if (!data->session->pending_media_state->topology) {
1339  return -1;
1340  }
1341  }
1342  topology = data->session->pending_media_state->topology;
1343  }
1344 
1345  /* XXX This method won't work when it comes time to do multistream support. The proper way to do this
1346  * will either be to
1347  * a) Alter all media streams of a particular type.
1348  * b) Change the dialplan function to be able to specify which stream to alter and alter only that
1349  * one stream
1350  */
1351  stream = ast_stream_topology_get_first_stream_by_type(topology, data->media_type);
1352  if (!stream) {
1353  return 0;
1354  }
1355 
1357  if (!caps) {
1358  return -1;
1359  }
1360 
1365  ast_stream_set_formats(stream, caps);
1366  ast_stream_set_metadata(stream, "pjsip_session_refresh", "force");
1367  ao2_ref(caps, -1);
1368 
1369  return 0;
1370 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
struct ast_sip_endpoint * endpoint
enum ast_media_type media_type
struct ast_sip_session_media_state * pending_media_state
struct ast_sip_session_media_state * media_state
Created proposed media state.
Session refresh state information.
struct pjsip_inv_session * inv_session
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
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
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
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.
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
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
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:525
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
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
struct ast_stream_topology * topology
Definition: res_pjsip.h:772
struct ast_stream_topology * topology
The media stream topology.
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
struct ast_sip_session * session
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

◆ parse_uri_cb()

static int parse_uri_cb ( void *  data)
static

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

References args, ast_copy_pj_str(), ast_log, AST_LOG_WARNING, ast_sip_get_pjsip_endpoint(), parse_uri_args::buf, parse_uri_args::buflen, LOG_ERROR, LOG_WARNING, pool, parse_uri_args::ret, tmp(), parse_uri_args::type, and parse_uri_args::uri.

Referenced by pjsip_acf_parse_uri_read().

1122 {
1123  struct parse_uri_args *args = data;
1124  pj_pool_t *pool;
1125  pjsip_name_addr *uri;
1126  pjsip_sip_uri *sip_uri;
1127  pj_str_t tmp;
1128 
1129  args->ret = 0;
1130 
1131  pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "ParseUri", 128, 128);
1132  if (!pool) {
1133  ast_log(LOG_ERROR, "Failed to allocate ParseUri endpoint pool.\n");
1134  args->ret = -1;
1135  return 0;
1136  }
1137 
1138  pj_strdup2_with_null(pool, &tmp, args->uri);
1139  uri = (pjsip_name_addr *)pjsip_parse_uri(pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
1140  if (!uri || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
1141  ast_log(LOG_WARNING, "Failed to parse URI '%s'\n", args->uri);
1142  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1143  args->ret = -1;
1144  return 0;
1145  }
1146 
1147  if (!strcmp(args->type, "scheme")) {
1148  ast_copy_pj_str(args->buf, pjsip_uri_get_scheme(uri), args->buflen);
1149  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1150  return 0;
1151  } else if (!strcmp(args->type, "display")) {
1152  ast_copy_pj_str(args->buf, &uri->display, args->buflen);
1153  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1154  return 0;
1155  }
1156 
1157  sip_uri = pjsip_uri_get_uri(uri);
1158  if (!sip_uri) {
1159  ast_log(LOG_ERROR, "Failed to get an URI object for '%s'\n", args->uri);
1160  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1161  args->ret = -1;
1162  return 0;
1163  }
1164 
1165  if (!strcmp(args->type, "user")) {
1166  ast_copy_pj_str(args->buf, &sip_uri->user, args->buflen);
1167  } else if (!strcmp(args->type, "passwd")) {
1168  ast_copy_pj_str(args->buf, &sip_uri->passwd, args->buflen);
1169  } else if (!strcmp(args->type, "host")) {
1170  ast_copy_pj_str(args->buf, &sip_uri->host, args->buflen);
1171  } else if (!strcmp(args->type, "port")) {
1172  snprintf(args->buf, args->buflen, "%d", sip_uri->port);
1173  } else if (!strcmp(args->type, "user_param")) {
1174  ast_copy_pj_str(args->buf, &sip_uri->user_param, args->buflen);
1175  } else if (!strcmp(args->type, "method_param")) {
1176  ast_copy_pj_str(args->buf, &sip_uri->method_param, args->buflen);
1177  } else if (!strcmp(args->type, "transport_param")) {
1178  ast_copy_pj_str(args->buf, &sip_uri->transport_param, args->buflen);
1179  } else if (!strcmp(args->type, "ttl_param")) {
1180  snprintf(args->buf, args->buflen, "%d", sip_uri->ttl_param);
1181  } else if (!strcmp(args->type, "lr_param")) {
1182  snprintf(args->buf, args->buflen, "%d", sip_uri->lr_param);
1183  } else if (!strcmp(args->type, "maddr_param")) {
1184  ast_copy_pj_str(args->buf, &sip_uri->maddr_param, args->buflen);
1185  } else {
1186  ast_log(AST_LOG_WARNING, "Unknown type part '%s' specified\n", args->type);
1187  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1188  args->ret = -1;
1189  return 0;
1190  }
1191 
1192  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1193 
1194  return 0;
1195 }
Struct used to push PJSIP_PARSE_URI function arguments to task processor.
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define AST_LOG_WARNING
Definition: logger.h:279
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:5240
const char * args
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3718

◆ 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 916 of file pjsip/dialplan_functions.c.

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, pjsip_func_args::buf, pjsip_func_args::field, pjsip_func_args::len, len(), LOG_ERROR, LOG_WARNING, pjsip_func_args::param, parse(), read_pjsip(), pjsip_func_args::ret, ast_sip_session::serializer, ast_sip_channel_pvt::session, pjsip_func_args::session, type, and pjsip_func_args::type.

917 {
918  struct pjsip_func_args func_args = { 0, };
920  char *parse = ast_strdupa(data);
921 
923  AST_APP_ARG(param);
924  AST_APP_ARG(type);
925  AST_APP_ARG(field);
926  );
927 
928  if (!chan) {
929  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
930  return -1;
931  }
932 
933  /* Check for zero arguments */
934  if (ast_strlen_zero(parse)) {
935  ast_log(LOG_ERROR, "Cannot call %s without arguments\n", cmd);
936  return -1;
937  }
938 
939  AST_STANDARD_APP_ARGS(args, parse);
940 
941  ast_channel_lock(chan);
942 
943  /* Sanity check */
944  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
945  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
946  ast_channel_unlock(chan);
947  return 0;
948  }
949 
950  channel = ast_channel_tech_pvt(chan);
951  if (!channel) {
952  ast_log(LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
953  ast_channel_unlock(chan);
954  return -1;
955  }
956 
957  if (!channel->session) {
958  ast_log(LOG_WARNING, "Channel %s has no session\n", ast_channel_name(chan));
959  ast_channel_unlock(chan);
960  return -1;
961  }
962 
963  func_args.session = ao2_bump(channel->session);
964  ast_channel_unlock(chan);
965 
966  memset(buf, 0, len);
967 
968  func_args.param = args.param;
969  func_args.type = args.type;
970  func_args.field = args.field;
971  func_args.buf = buf;
972  func_args.len = len;
973  if (ast_sip_push_task_wait_serializer(func_args.session->serializer, read_pjsip, &func_args)) {
974  ast_log(LOG_WARNING, "Unable to read properties of channel %s: failed to push task\n", ast_channel_name(chan));
975  ao2_ref(func_args.session, -1);
976  return -1;
977  }
978  ao2_ref(func_args.session, -1);
979 
980  return func_args.ret;
981 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
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
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
static int read_pjsip(void *data)
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
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:5218
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with &#39;\0&#39; ...
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_sip_session * session
Struct used to push function arguments to task processor.
#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)
#define AST_APP_ARG(name)
Define an application argument.

◆ 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 983 of file pjsip/dialplan_functions.c.

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, LOG_WARNING, NULL, RAII_VAR, S_OR, strsep(), and ast_sip_contact::uri.

984 {
985  RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
986  RAII_VAR(struct ast_str *, dial, NULL, ast_free_ptr);
987  const char *aor_name;
988  char *rest;
989 
991  AST_APP_ARG(endpoint_name);
992  AST_APP_ARG(aor_name);
993  AST_APP_ARG(request_user);
994  );
995 
997 
998  if (ast_strlen_zero(args.endpoint_name)) {
999  ast_log(LOG_WARNING, "An endpoint name must be specified when using the '%s' dialplan function\n", cmd);
1000  return -1;
1001  } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", args.endpoint_name))) {
1002  ast_log(LOG_WARNING, "Specified endpoint '%s' was not found\n", args.endpoint_name);
1003  return -1;
1004  }
1005 
1006  aor_name = S_OR(args.aor_name, endpoint->aors);
1007 
1008  if (ast_strlen_zero(aor_name)) {
1009  ast_log(LOG_WARNING, "No AOR has been provided and no AORs are configured on endpoint '%s'\n", args.endpoint_name);
1010  return -1;
1011  } else if (!(dial = ast_str_create(len))) {
1012  ast_log(LOG_WARNING, "Could not get enough buffer space for dialing contacts\n");
1013  return -1;
1014  } else if (!(rest = ast_strdupa(aor_name))) {
1015  ast_log(LOG_WARNING, "Could not duplicate provided AORs\n");
1016  return -1;
1017  }
1018 
1019  while ((aor_name = ast_strip(strsep(&rest, ",")))) {
1021  RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
1022  struct ao2_iterator it_contacts;
1023  struct ast_sip_contact *contact;
1024 
1025  if (!aor) {
1026  /* If the AOR provided is not found skip it, there may be more */
1027  continue;
1029  /* No contacts are available, skip it as well */
1030  continue;
1031  } else if (!ao2_container_count(contacts)) {
1032  /* We were given a container but no contacts are in it... */
1033  continue;
1034  }
1035 
1036  it_contacts = ao2_iterator_init(contacts, 0);
1037  for (; (contact = ao2_iterator_next(&it_contacts)); ao2_ref(contact, -1)) {
1038  ast_str_append(&dial, -1, "PJSIP/");
1039 
1040  if (!ast_strlen_zero(args.request_user)) {
1041  ast_str_append(&dial, -1, "%s@", args.request_user);
1042  }
1043  ast_str_append(&dial, -1, "%s/%s&", args.endpoint_name, contact->uri);
1044  }
1045  ao2_iterator_destroy(&it_contacts);
1046  }
1047 
1048  /* Trim the '&' at the end off */
1049  ast_str_truncate(dial, ast_str_strlen(dial) - 1);
1050 
1052 
1053  return 0;
1054 }
A SIP address of record.
Definition: res_pjsip.h:361
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
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
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:1091
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const char * args
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
#define ast_strlen_zero(foo)
Definition: strings.h:52
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
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
Definition: location.c:147
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Contact associated with an address of record.
Definition: res_pjsip.h:281
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
const ast_string_field aor
Definition: res_pjsip.h:303
char * strsep(char **str, const char *delims)
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
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
Return only reachable or unknown contacts.
Definition: res_pjsip.h:1009
Generic container type.
const ast_string_field uri
Definition: res_pjsip.h:303
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define AST_APP_ARG(name)
Define an application argument.

◆ 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 1429 of file pjsip/dialplan_functions.c.

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

1430 {
1431  struct ast_sip_channel_pvt *channel;
1432 
1433  if (!chan) {
1434  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1435  return -1;
1436  }
1437 
1438  ast_channel_lock(chan);
1439  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1440  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1441  ast_channel_unlock(chan);
1442  return -1;
1443  }
1444 
1445  channel = ast_channel_tech_pvt(chan);
1446 
1447  if (ast_sip_dtmf_to_str(channel->session->dtmf, buf, len) < 0) {
1448  ast_log(LOG_WARNING, "Unknown DTMF mode %d on PJSIP channel %s\n", channel->session->dtmf, ast_channel_name(chan));
1449  ast_channel_unlock(chan);
1450  return -1;
1451  }
1452 
1453  ast_channel_unlock(chan);
1454  return 0;
1455 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
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:5484
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_sip_dtmf_mode dtmf
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * ast_channel_name(const struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ 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 1530 of file pjsip/dialplan_functions.c.

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, ast_sip_channel_pvt::session, refresh_data::session, and type.

1531 {
1532  struct ast_sip_channel_pvt *channel;
1533  struct ast_sip_session_media *media;
1534  int dsp_features = 0;
1535  int dtmf = -1;
1536  struct refresh_data rdata = {
1538  };
1539 
1540  if (!chan) {
1541  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1542  return -1;
1543  }
1544 
1545  ast_channel_lock(chan);
1546  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1547  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1548  ast_channel_unlock(chan);
1549  return -1;
1550  }
1551 
1552  channel = ast_channel_tech_pvt(chan);
1553  rdata.session = channel->session;
1554 
1555  dtmf = ast_sip_str_to_dtmf(value);
1556 
1557  if (dtmf == -1) {
1558  ast_log(LOG_WARNING, "Cannot set DTMF mode to '%s' on channel '%s' as value is invalid.\n", value,
1559  ast_channel_name(chan));
1560  ast_channel_unlock(chan);
1561  return -1;
1562  }
1563 
1564  if (channel->session->dtmf == dtmf) {
1565  /* DTMF mode unchanged, nothing to do! */
1566  ast_channel_unlock(chan);
1567  return 0;
1568  }
1569 
1570  channel->session->dtmf = dtmf;
1571 
1573 
1574  if (media && media->rtp) {
1575  if (channel->session->dtmf == AST_SIP_DTMF_RFC_4733) {
1578  } else if (channel->session->dtmf == AST_SIP_DTMF_INFO) {
1581  } else if (channel->session->dtmf == AST_SIP_DTMF_INBAND) {
1584  } else if (channel->session->dtmf == AST_SIP_DTMF_NONE) {
1587  } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO) {
1589  /* no RFC4733 negotiated, enable inband */
1591  }
1592  } else if (channel->session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
1595  /* if inband, switch to INFO */
1597  }
1598  }
1599  }
1600 
1601  if (channel->session->dsp) {
1602  dsp_features = ast_dsp_get_features(channel->session->dsp);
1603  }
1604  if (channel->session->dtmf == AST_SIP_DTMF_INBAND ||
1605  channel->session->dtmf == AST_SIP_DTMF_AUTO) {
1606  dsp_features |= DSP_FEATURE_DIGIT_DETECT;
1607  } else {
1608  dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
1609  }
1610  if (dsp_features) {
1611  if (!channel->session->dsp) {
1612  if (!(channel->session->dsp = ast_dsp_new())) {
1613  ast_channel_unlock(chan);
1614  return 0;
1615  }
1616  }
1617  ast_dsp_set_features(channel->session->dsp, dsp_features);
1618  } else if (channel->session->dsp) {
1619  ast_dsp_free(channel->session->dsp);
1620  channel->session->dsp = NULL;
1621  }
1622 
1623  ast_channel_unlock(chan);
1624 
1626 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_channel_lock(chan)
Definition: channel.h:2945
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:2123
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
#define LOG_WARNING
Definition: logger.h:274
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
int ast_sip_str_to_dtmf(const char *dtmf_mode)
Convert the DTMF mode name into an enum.
Definition: res_pjsip.c:5513
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
struct ast_sip_session_media_state * active_media_state
enum ast_sip_session_refresh_method method
struct ast_dsp * dsp
#define ast_log
Definition: astobj2.c:42
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1764
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:5218
struct ast_taskprocessor * serializer
enum ast_sip_dtmf_mode dtmf
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
struct ast_sip_session * session
static int dtmf_mode_refresh_cb(void *obj)
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
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:2137
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
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ 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 1372 of file pjsip/dialplan_functions.c.

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

1373 {
1374  struct ast_sip_channel_pvt *channel;
1375 
1376  if (!chan) {
1377  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1378  return -1;
1379  }
1380 
1381  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1382  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1383  return -1;
1384  }
1385 
1386  channel = ast_channel_tech_pvt(chan);
1387 
1388  if (!strcmp(data, "audio")) {
1390  } else if (!strcmp(data, "video")) {
1392  } else {
1393  /* Ensure that the buffer is empty */
1394  buf[0] = '\0';
1395  }
1396 
1397  return 0;
1398 }
static const char type[]
Definition: chan_ooh323.c:109
void * ast_channel_tech_pvt(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int media_offer_read_av(struct ast_sip_session *session, char *buf, size_t len, enum ast_media_type media_type)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ 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 1400 of file pjsip/dialplan_functions.c.

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, ast_sip_channel_pvt::session, media_offer_data::session, type, and media_offer_data::value.

1401 {
1402  struct ast_sip_channel_pvt *channel;
1403  struct media_offer_data mdata = {
1404  .value = value
1405  };
1406 
1407  if (!chan) {
1408  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1409  return -1;
1410  }
1411 
1412  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1413  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1414  return -1;
1415  }
1416 
1417  channel = ast_channel_tech_pvt(chan);
1418  mdata.session = channel->session;
1419 
1420  if (!strcmp(data, "audio")) {
1422  } else if (!strcmp(data, "video")) {
1424  }
1425 
1427 }
static const char type[]
Definition: chan_ooh323.c:109
enum ast_media_type media_type
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
static int media_offer_write_av(void *obj)
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
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:5218
struct ast_taskprocessor * serializer
struct ast_sip_session * session
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ 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 1457 of file pjsip/dialplan_functions.c.

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

1458 {
1459  struct ast_sip_channel_pvt *channel;
1460 
1461  if (!chan) {
1462  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1463  return -1;
1464  }
1465 
1466  if (len < 3) {
1467  ast_log(LOG_WARNING, "%s: buffer too small\n", cmd);
1468  return -1;
1469  }
1470 
1471  ast_channel_lock(chan);
1472  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1473  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1474  ast_channel_unlock(chan);
1475  return -1;
1476  }
1477 
1478  channel = ast_channel_tech_pvt(chan);
1479  strncpy(buf, AST_YESNO(channel->session->moh_passthrough), len);
1480 
1481  ast_channel_unlock(chan);
1482  return 0;
1483 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:139
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
unsigned int moh_passthrough

◆ 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 1628 of file pjsip/dialplan_functions.c.

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, and type.

1629 {
1630  struct ast_sip_channel_pvt *channel;
1631 
1632  if (!chan) {
1633  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1634  return -1;
1635  }
1636 
1637  ast_channel_lock(chan);
1638  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1639  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1640  ast_channel_unlock(chan);
1641  return -1;
1642  }
1643 
1644  channel = ast_channel_tech_pvt(chan);
1645  channel->session->moh_passthrough = ast_true(value);
1646 
1647  ast_channel_unlock(chan);
1648 
1649  return 0;
1650 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
unsigned int moh_passthrough

◆ 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 1197 of file pjsip/dialplan_functions.c.

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::buf, parse_uri_args::buflen, LOG_WARNING, NULL, parse_uri_cb(), parse_uri_args::ret, type, parse_uri_args::type, and parse_uri_args::uri.

1198 {
1199  struct parse_uri_args func_args = { 0, };
1200 
1202  AST_APP_ARG(uri_str);
1203  AST_APP_ARG(type);
1204  );
1205 
1206  AST_STANDARD_APP_ARGS(args, data);
1207 
1208  if (ast_strlen_zero(args.uri_str)) {
1209  ast_log(LOG_WARNING, "An URI must be specified when using the '%s' dialplan function\n", cmd);
1210  return -1;
1211  }
1212 
1213  if (ast_strlen_zero(args.type)) {
1214  ast_log(LOG_WARNING, "A type part of the URI must be specified when using the '%s' dialplan function\n", cmd);
1215  return -1;
1216  }
1217 
1218  memset(buf, 0, buflen);
1219 
1220  func_args.uri = args.uri_str;
1221  func_args.type = args.type;
1222  func_args.buf = buf;
1223  func_args.buflen = buflen;
1225  ast_log(LOG_WARNING, "Unable to parse URI: failed to push task\n");
1226  return -1;
1227  }
1228 
1229  return func_args.ret;
1230 }
static const char type[]
Definition: chan_ooh323.c:109
Struct used to push PJSIP_PARSE_URI function arguments to task processor.
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
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int parse_uri_cb(void *data)
#define ast_log
Definition: astobj2.c:42
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:5218
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with &#39;\0&#39; ...
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ 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 1671 of file pjsip/dialplan_functions.c.

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, ast_sip_channel_pvt::session, refresh_data::session, and type.

1672 {
1673  struct ast_sip_channel_pvt *channel;
1674  struct refresh_data rdata = {
1676  };
1677 
1678  if (!chan) {
1679  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1680  return -1;
1681  }
1682 
1683  if (ast_channel_state(chan) != AST_STATE_UP) {
1684  ast_log(LOG_WARNING, "'%s' not allowed on unanswered channel '%s'.\n", cmd, ast_channel_name(chan));
1685  return -1;
1686  }
1687 
1688  if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
1689  ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
1690  return -1;
1691  }
1692 
1693  channel = ast_channel_tech_pvt(chan);
1694  rdata.session = channel->session;
1695 
1696  if (!strcmp(value, "invite")) {
1698  } else if (!strcmp(value, "update")) {
1700  }
1701 
1703 }
static const char type[]
Definition: chan_ooh323.c:109
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
ast_channel_state
ast_channel states
Definition: channelstate.h:35
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
int value
Definition: syslog.c:37
enum ast_sip_session_refresh_method method
#define ast_log
Definition: astobj2.c:42
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:5218
struct ast_taskprocessor * serializer
struct ast_sip_session * session
static int refresh_write_cb(void *obj)
const char * ast_channel_name(const struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ 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 736 of file pjsip/dialplan_functions.c.

References ast_channel_name(), ast_escape_quoted(), ast_log, ast_strdupa, and LOG_ERROR.

Referenced by channel_read_pjsip().

738 {
739  int res;
740  char *buf_copy;
741 
742  res = pjsip_uri_print(context, uri, buf, size);
743  if (res < 0) {
744  ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n",
745  ast_channel_name(chan), type, (int) size);
746 
747  /* Empty buffer that likely is not terminated. */
748  buf[0] = '\0';
749  return -1;
750  }
751 
752  buf_copy = ast_strdupa(buf);
753  ast_escape_quoted(buf_copy, buf, size);
754  return 0;
755 }
static const char type[]
Definition: chan_ooh323.c:109
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:635
const char * ast_channel_name(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ read_pjsip()

static int read_pjsip ( void *  data)
static

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

References ast_sip_session::aor, ast_channel_name(), ast_log, AST_LOG_WARNING, ast_sorcery_object_get_id(), pjsip_func_args::buf, ast_sip_session::channel, channel_read_pjsip(), channel_read_rtcp(), channel_read_rtp(), ast_sip_session::contact, ast_sip_session::endpoint, pjsip_func_args::field, func_args(), pjsip_func_args::len, pjsip_func_args::param, pjsip_func_args::ret, pjsip_func_args::session, and pjsip_func_args::type.

Referenced by pjsip_acf_channel_read().

863 {
864  struct pjsip_func_args *func_args = data;
865 
866  if (!strcmp(func_args->param, "rtp")) {
867  if (!func_args->session->channel) {
868  func_args->ret = -1;
869  return 0;
870  }
871  func_args->ret = channel_read_rtp(func_args->session->channel, func_args->type,
872  func_args->field, func_args->buf,
873  func_args->len);
874  } else if (!strcmp(func_args->param, "rtcp")) {
875  if (!func_args->session->channel) {
876  func_args->ret = -1;
877  return 0;
878  }
879  func_args->ret = channel_read_rtcp(func_args->session->channel, func_args->type,
880  func_args->field, func_args->buf,
881  func_args->len);
882  } else if (!strcmp(func_args->param, "endpoint")) {
883  if (!func_args->session->endpoint) {
884  ast_log(AST_LOG_WARNING, "Channel %s has no endpoint!\n", func_args->session->channel ?
885  ast_channel_name(func_args->session->channel) : "<unknown>");
886  func_args->ret = -1;
887  return 0;
888  }
889  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->endpoint));
890  } else if (!strcmp(func_args->param, "contact")) {
891  if (!func_args->session->contact) {
892  return 0;
893  }
894  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->contact));
895  } else if (!strcmp(func_args->param, "aor")) {
896  if (!func_args->session->aor) {
897  return 0;
898  }
899  snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->aor));
900  } else if (!strcmp(func_args->param, "pjsip")) {
901  if (!func_args->session->channel) {
902  func_args->ret = -1;
903  return 0;
904  }
905  func_args->ret = channel_read_pjsip(func_args->session->channel, func_args->type,
906  func_args->field, func_args->buf,
907  func_args->len);
908  } else {
909  func_args->ret = -1;
910  }
911 
912  return 0;
913 }
struct ast_sip_endpoint * endpoint
static int channel_read_rtcp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
#define AST_LOG_WARNING
Definition: logger.h:279
static int channel_read_rtp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
#define ast_log
Definition: astobj2.c:42
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with &#39;\0&#39; ...
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ast_channel * channel
static int channel_read_pjsip(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen)
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_sip_session * session
Struct used to push function arguments to task processor.
struct ast_sip_contact * contact
struct ast_sip_aor * aor

◆ refresh_write_cb()

static int refresh_write_cb ( void *  obj)
static

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

References ast_sip_session_refresh(), ast_sip_session_remove_datastore(), session_refresh_state::media_state, 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().

1653 {
1654  struct refresh_data *data = obj;
1655  struct session_refresh_state *state;
1656 
1658  if (!state) {
1659  return -1;
1660  }
1661 
1663  sip_session_response_cb, data->method, 1, state->media_state);
1664 
1665  state->media_state = NULL;
1666  ast_sip_session_remove_datastore(data->session, "pjsip_session_refresh");
1667 
1668  return 0;
1669 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
struct ast_sip_session_media_state * media_state
Created proposed media state.
Session refresh state information.
#define NULL
Definition: resample.c:96
enum ast_sip_session_refresh_method method
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.
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.
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_sip_session * session

◆ session_refresh_state_destroy()

static void session_refresh_state_destroy ( void *  obj)
static

Destructor for session refresh information.

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

References ast_free, ast_sip_session_media_state_free(), and session_refresh_state::media_state.

1064 {
1065  struct session_refresh_state *state = obj;
1066 
1068  ast_free(obj);
1069 }
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.
struct ast_sip_session_media_state * media_state
Created proposed media state.
Session refresh state information.
#define ast_free(a)
Definition: astmm.h:182

◆ 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 1078 of file pjsip/dialplan_functions.c.

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(), ast_sip_session::endpoint, ast_sip_endpoint::media, session_refresh_state::media_state, NULL, RAII_VAR, state, ast_sip_session_media_state::topology, and ast_sip_endpoint_media_configuration::topology.

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

1079 {
1080  RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "pjsip_session_refresh"), ao2_cleanup);
1081  struct session_refresh_state *state;
1082 
1083  /* While the datastore refcount is decremented this is operating in the serializer so it will remain valid regardless */
1084  if (datastore) {
1085  return datastore->data;
1086  }
1087 
1088  if (!(datastore = ast_sip_session_alloc_datastore(&session_refresh_datastore, "pjsip_session_refresh"))
1089  || !(datastore->data = ast_calloc(1, sizeof(struct session_refresh_state)))
1090  || ast_sip_session_add_datastore(session, datastore)) {
1091  return NULL;
1092  }
1093 
1094  state = datastore->data;
1096  if (!state->media_state) {
1097  ast_sip_session_remove_datastore(session, "pjsip_session_refresh");
1098  return NULL;
1099  }
1101  if (!state->media_state->topology) {
1102  ast_sip_session_remove_datastore(session, "pjsip_session_refresh");
1103  return NULL;
1104  }
1105 
1106  datastore->data = state;
1107 
1108  return state;
1109 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
struct ast_sip_endpoint * endpoint
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.
struct ast_sip_session_media_state * media_state
Created proposed media state.
Session refresh state information.
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static const struct ast_datastore_info session_refresh_datastore
Datastore for attaching session refresh state information.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
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
struct ast_stream_topology * topology
Definition: res_pjsip.h:772
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_stream_topology * topology
The media stream topology.
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.

◆ sip_session_response_cb()

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

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

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 ast_sip_session::channel.

Referenced by dtmf_mode_refresh_cb(), and refresh_write_cb().

1491 {
1492  struct ast_format *fmt;
1493 
1494  if (!session->channel) {
1495  /* Egads! */
1496  return 0;
1497  }
1498 
1500  if (!fmt) {
1501  /* No format? That's weird. */
1502  return 0;
1503  }
1504  ast_channel_set_writeformat(session->channel, fmt);
1505  ast_channel_set_rawwriteformat(session->channel, fmt);
1506  ast_channel_set_readformat(session->channel, fmt);
1507  ast_channel_set_rawreadformat(session->channel, fmt);
1508  ao2_ref(fmt, -1);
1509 
1510  return 0;
1511 }
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
Definition of a media format.
Definition: format.c:43
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
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
struct ast_channel * channel
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)

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 1072 of file pjsip/dialplan_functions.c.

◆ t38state_to_string

const char* t38state_to_string[T38_MAX_ENUM]
static

String representations of the T.38 state enum.

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

Referenced by channel_read_pjsip().