Asterisk - The Open Source Telephony Project  GIT-master-9ed6387
Data Structures | Macros | Functions | Variables
chan_pjsip.c File Reference

PSJIP SIP Channel Driver. More...

#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include <pjlib.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/causes.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/dsp.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/indications.h"
#include "asterisk/format_cache.h"
#include "asterisk/translate.h"
#include "asterisk/threadstorage.h"
#include "asterisk/features_config.h"
#include "asterisk/pickup.h"
#include "asterisk/test.h"
#include "asterisk/message.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/stream.h"
#include "pjsip/include/chan_pjsip.h"
#include "pjsip/include/dialplan_functions.h"
#include "pjsip/include/cli_functions.h"

Go to the source code of this file.

Data Structures

struct  answer_data
 
struct  hangup_data
 
struct  indicate_data
 
struct  info_dtmf_data
 
struct  request_data
 
struct  rtp_direct_media_data
 
struct  sendtext_data
 
struct  topology_change_refresh_data
 
struct  transfer_data
 

Macros

#define UNIQUEID_BUFSIZE   256
 

Functions

static void __init_uniqueid_threadbuf (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static int answer (void *data)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int call (void *data)
 
static int call_pickup_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
static int chan_pjsip_add_hold (const char *chan_uid)
 Add a channel ID to the list of PJSIP channels on hold. More...
 
static int chan_pjsip_answer (struct ast_channel *ast)
 Function called by core when we should answer a PJSIP session. More...
 
static int chan_pjsip_call (struct ast_channel *ast, const char *dest, int timeout)
 Function called by core to actually start calling a remote party. More...
 
static struct ast_framechan_pjsip_cng_tone_detected (struct ast_channel *ast, struct ast_sip_session *session, struct ast_frame *f)
 Internal helper function called when CNG tone is detected. More...
 
static int chan_pjsip_devicestate (const char *data)
 Function called to get the device state of an endpoint. More...
 
static int chan_pjsip_digit_begin (struct ast_channel *chan, char digit)
 Function called by core to start a DTMF digit. More...
 
static int chan_pjsip_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Function called by core to stop a DTMF digit. More...
 
static int chan_pjsip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 Function called by core to change the underlying owner channel. More...
 
static void chan_pjsip_get_codec (struct ast_channel *chan, struct ast_format_cap *result)
 Function called by RTP engine to get peer capabilities. More...
 
static int chan_pjsip_get_hold (const char *chan_uid)
 Determine whether a channel ID is in the list of PJSIP channels on hold. More...
 
static enum ast_rtp_glue_result chan_pjsip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
 Function called by RTP engine to get local audio RTP peer. More...
 
static const char * chan_pjsip_get_uniqueid (struct ast_channel *ast)
 
static enum ast_rtp_glue_result chan_pjsip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
 Function called by RTP engine to get local video RTP peer. More...
 
static int chan_pjsip_hangup (struct ast_channel *ast)
 Function called by core to hang up a PJSIP session. More...
 
static int chan_pjsip_incoming_ack (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 
static int chan_pjsip_incoming_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 Function called when a request is received on the session. More...
 
static void chan_pjsip_incoming_response (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 Function called when a response is received on the session. More...
 
static int chan_pjsip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Function called by core to ask the channel to indicate some sort of condition. More...
 
static struct ast_channelchan_pjsip_new (struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
 Function called to create a new PJSIP Asterisk channel. More...
 
static void chan_pjsip_pvt_dtor (void *obj)
 
static int chan_pjsip_queryoption (struct ast_channel *ast, int option, void *data, int *datalen)
 Function called to query options on a channel. More...
 
static struct ast_framechan_pjsip_read_stream (struct ast_channel *ast)
 Function called by core to read any waiting frames. More...
 
static void chan_pjsip_remove_hold (const char *chan_uid)
 Remove a channel ID from the list of PJSIP channels on hold. More...
 
static struct ast_channelchan_pjsip_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 
static struct ast_channelchan_pjsip_request_with_stream_topology (const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 Function called by core to create a new outgoing PJSIP session. More...
 
static int chan_pjsip_sendtext (struct ast_channel *ast, const char *text)
 
static int chan_pjsip_sendtext_data (struct ast_channel *ast, struct ast_msg_data *msg)
 Function called by core to send text on PJSIP session. More...
 
static void chan_pjsip_session_begin (struct ast_sip_session *session)
 SIP session interaction functions. More...
 
static void chan_pjsip_session_end (struct ast_sip_session *session)
 Function called when the session ends. More...
 
static int chan_pjsip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
 Function called by RTP engine to change where the remote party should send media. More...
 
static int chan_pjsip_transfer (struct ast_channel *chan, const char *target)
 Function called by core for Asterisk initiated transfer. More...
 
static int chan_pjsip_write (struct ast_channel *ast, struct ast_frame *f)
 
static int chan_pjsip_write_stream (struct ast_channel *ast, int stream_num, struct ast_frame *f)
 
static int check_for_rtp_changes (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_sip_session_media *media, struct ast_sip_session *session)
 
static void clear_session_and_channel (struct ast_sip_session *session, struct ast_channel *ast)
 Clear a channel from a session along with its PVT. More...
 
static int compatible_formats_exist (struct ast_stream_topology *top, struct ast_format_cap *cap)
 Determine if a topology is compatible with format capabilities. More...
 
static int direct_media_mitigate_glare (struct ast_sip_session *session)
 
static int handle_topology_request_change (struct ast_sip_session *session, const struct ast_stream_topology *proposed)
 
static int hangup (void *data)
 
static int hangup_cause2sip (int cause)
 Internal function which translates from Asterisk cause codes to SIP response codes. More...
 
static struct hangup_datahangup_data_alloc (int cause, struct ast_channel *chan)
 
static void hangup_data_destroy (void *obj)
 
static int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes. More...
 
static int indicate (void *data)
 
static struct indicate_dataindicate_data_alloc (struct ast_sip_session *session, int condition, int response_code, const void *frame_data, size_t datalen)
 
static void indicate_data_destroy (void *obj)
 
static struct info_dtmf_datainfo_dtmf_data_alloc (struct ast_sip_session *session, char digit, unsigned int duration)
 
static void info_dtmf_data_destroy (void *obj)
 
static int is_colp_update_allowed (struct ast_sip_session *session)
 
static int is_compatible_format (struct ast_sip_session *session, struct ast_frame *f)
 Determine if the given frame is in a format we've negotiated. More...
 
static int load_module (void)
 Load the module. More...
 
static void local_hold_set_state (struct ast_sip_session_media *session_media, unsigned int held)
 Callback which changes the value of locally held on the media stream. More...
 
static int on_topology_change_response (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
static int pbx_start_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
static int remote_send_hold (void *data)
 Update local hold state to be held. More...
 
static int remote_send_hold_refresh (struct ast_sip_session *session, unsigned int held)
 Update local hold state and send a re-INVITE with the new SDP. More...
 
static int remote_send_unhold (void *data)
 Update local hold state to be unheld. More...
 
static int request (void *obj)
 
static struct rtp_direct_media_datartp_direct_media_data_create (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, const struct ast_format_cap *cap, struct ast_sip_session *session)
 
static void rtp_direct_media_data_destroy (void *data)
 
static int rtp_find_rtcp_fd_position (struct ast_sip_session *session, struct ast_rtp_instance *rtp)
 Helper function to find the position for RTCP. More...
 
static int send_direct_media_request (void *data)
 
static int send_topology_change_refresh (void *data)
 
static int sendtext (void *obj)
 
static struct sendtext_datasendtext_data_create (struct ast_channel *chan, struct ast_msg_data *msg)
 
static void sendtext_data_destroy (void *obj)
 
static void set_channel_on_rtp_instance (const struct ast_sip_session *session, const char *channel_id)
 
static struct topology_change_refresh_datatopology_change_refresh_data_alloc (struct ast_sip_session *session, const struct ast_stream_topology *topology)
 
static void topology_change_refresh_data_free (struct topology_change_refresh_data *refresh_data)
 
static int transfer (void *data)
 
static struct transfer_datatransfer_data_alloc (struct ast_sip_session *session, const char *target)
 
static void transfer_data_destroy (void *obj)
 
static void transfer_redirect (struct ast_sip_session *session, const char *target)
 
static void transfer_refer (struct ast_sip_session *session, const char *target)
 
static int transmit_info_dtmf (void *data)
 
static int transmit_info_with_vidupdate (void *data)
 Send SIP INFO with video update request. More...
 
static void transport_info_destroy (void *obj)
 Destructor function for transport_info_data. More...
 
static int uid_hold_hash_fn (const void *obj, const int flags)
 
static int uid_hold_sort_fn (const void *obj_left, const void *obj_right, const int flags)
 
static int unload_module (void)
 Unload the PJSIP channel from Asterisk. More...
 
static int update_connected_line_information (void *data)
 Update connected line information. More...
 
static int update_devstate (void *obj, void *arg, int flags)
 
static void update_initial_connected_line (struct ast_sip_session *session)
 
static void xfer_client_on_evsub_state (pjsip_evsub *sub, pjsip_event *event)
 Callback function to report status of implicit REFER-NOTIFY subscription. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "res_pjsip,res_pjsip_session,res_pjsip_pubsub", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_session_supplement call_pickup_supplement
 
static unsigned int chan_idx
 
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
 
static struct ast_custom_function chan_pjsip_dial_contacts_function
 
static struct ast_custom_function chan_pjsip_parse_uri_function
 
static struct ast_rtp_glue chan_pjsip_rtp_glue
 Local glue for interacting with the RTP engine core. More...
 
static struct ast_sip_session_supplement chan_pjsip_supplement
 SIP session supplement structure. More...
 
static struct ast_sip_session_supplement chan_pjsip_supplement_response
 SIP session supplement structure just for responses. More...
 
struct ast_channel_tech chan_pjsip_tech
 PBX interface structure for channel registration. More...
 
static const char channel_type [] = "PJSIP"
 
static struct ast_datastore_info direct_media_mitigation_info = { }
 
static struct ast_custom_function dtmf_mode_function
 
static struct ast_custom_function media_offer_function
 
static struct ast_custom_function moh_passthrough_function
 
static struct ast_sip_session_supplement pbx_start_supplement
 
static struct ao2_containerpjsip_uids_onhold
 
static pjsip_module refer_callback_module
 REFER Callback module, used to attach session data structure to subscription. More...
 
static struct ast_custom_function session_refresh_function
 
static struct ast_datastore_info transport_info
 Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel. More...
 
static struct ast_threadstorage uniqueid_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_uniqueid_threadbuf , .custom_init = NULL , }
 

Detailed Description

PSJIP SIP Channel Driver.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file chan_pjsip.c.

Macro Definition Documentation

◆ UNIQUEID_BUFSIZE

#define UNIQUEID_BUFSIZE   256

Definition at line 76 of file chan_pjsip.c.

Referenced by chan_pjsip_get_uniqueid().

Function Documentation

◆ __init_uniqueid_threadbuf()

static void __init_uniqueid_threadbuf ( void  )
static

Definition at line 75 of file chan_pjsip.c.

83 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3490 of file chan_pjsip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3490 of file chan_pjsip.c.

◆ answer()

static int answer ( void *  data)
static

Definition at line 680 of file chan_pjsip.c.

References ast_channel_name(), ast_log, ast_sip_session_get_name(), ast_sip_session_send_response(), ast_sip_session::channel, answer_data::indent, ast_sip_session::inv_session, LOG_ERROR, LOG_WARNING, NULL, SCOPE_ENTER_TASK, SCOPE_EXIT_RTN_VALUE, answer_data::session, and status.

Referenced by ast_raw_answer(), chan_pjsip_answer(), dns_parse_answer(), dns_parse_answer_ex(), dump_answer(), find_and_retrans(), pbx_builtin_incomplete(), session_inv_on_rx_offer(), stun_monitor_request(), tds_log(), verify_mock_cdr_record(), and zapateller_exec().

681 {
682  struct answer_data *ans_data = data;
683  pj_status_t status = PJ_SUCCESS;
684  pjsip_tx_data *packet = NULL;
685  struct ast_sip_session *session = ans_data->session;
686  SCOPE_ENTER_TASK(1, ans_data->indent, "%s\n", ast_sip_session_get_name(session));
687 
688  if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
689  ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
690  session->inv_session->cause,
691  pjsip_get_status_text(session->inv_session->cause)->ptr);
692 #ifdef HAVE_PJSIP_INV_SESSION_REF
693  pjsip_inv_dec_ref(session->inv_session);
694 #endif
695  SCOPE_EXIT_RTN_VALUE(0, "Disconnected\n");
696  }
697 
698  pjsip_dlg_inc_lock(session->inv_session->dlg);
699  if (session->inv_session->invite_tsx) {
700  status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet);
701  } else {
702  ast_log(LOG_ERROR,"Cannot answer '%s' because there is no associated SIP transaction\n",
703  ast_channel_name(session->channel));
704  }
705  pjsip_dlg_dec_lock(session->inv_session->dlg);
706 
707  if (status == PJ_SUCCESS && packet) {
708  ast_sip_session_send_response(session, packet);
709  }
710 
711 #ifdef HAVE_PJSIP_INV_SESSION_REF
712  pjsip_inv_dec_ref(session->inv_session);
713 #endif
714 
715  if (status != PJ_SUCCESS) {
716  char err[PJ_ERR_MSG_SIZE];
717 
718  pj_strerror(status, err, sizeof(err));
719  ast_log(LOG_WARNING,"Cannot answer '%s': %s\n",
720  ast_channel_name(session->channel), err);
721  /*
722  * Return this value so we can distinguish between this
723  * failure and the threadpool synchronous push failing.
724  */
725  SCOPE_EXIT_RTN_VALUE(-2, "pjproject failure\n");
726  }
728 }
#define SCOPE_ENTER_TASK(level, indent,...)
Definition: logger.h:873
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
A structure describing a SIP session.
#define ast_log
Definition: astobj2.c:42
unsigned long indent
Definition: chan_pjsip.c:677
static struct ast_mansession session
struct ast_channel * channel
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
#define LOG_ERROR
Definition: logger.h:285
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_sip_session * session
Definition: chan_pjsip.c:676
jack_status_t status
Definition: app_jack.c:146

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3490 of file chan_pjsip.c.

◆ call()

static int call ( void *  data)
static

Definition at line 2425 of file chan_pjsip.c.

References ao2_ref, ast_channel_name(), ast_channel_uniqueid(), ast_queue_hangup(), ast_set_hangupsource(), ast_sip_session_create_invite(), ast_sip_session_get_name(), ast_sip_session_send_request(), ast_str_tmp, ast_stream_topology_to_str(), ast_sip_session::channel, ast_sip_session::pending_media_state, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, ast_sip_channel_pvt::session, set_channel_on_rtp_instance(), ast_sip_session_media_state::topology, and update_initial_connected_line().

Referenced by ast_call(), chan_pjsip_call(), and native_start().

2426 {
2427  struct ast_sip_channel_pvt *channel = data;
2428  struct ast_sip_session *session = channel->session;
2429  pjsip_tx_data *tdata;
2430  int res = 0;
2431  SCOPE_ENTER(1, "%s Topology: %s\n",
2432  ast_sip_session_get_name(session),
2434  );
2435 
2436 
2437  res = ast_sip_session_create_invite(session, &tdata);
2438 
2439  if (res) {
2440  ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2441  ast_queue_hangup(session->channel);
2442  } else {
2445  ast_sip_session_send_request(session, tdata);
2446  }
2447  ao2_ref(channel, -1);
2448  SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
2449 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1146
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
struct ast_sip_session_media_state * pending_media_state
int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
Creates an INVITE request.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
A structure describing a SIP session.
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:492
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:921
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2479
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
struct ast_stream_topology * topology
The media stream topology.
const char * ast_channel_name(const struct ast_channel *chan)
static void update_initial_connected_line(struct ast_sip_session *session)
Definition: chan_pjsip.c:2400

◆ call_pickup_incoming_request()

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

Definition at line 3132 of file chan_pjsip.c.

References ao2_ref, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_hangupcause_set(), ast_channel_ref, ast_channel_unref, ast_get_chan_features_pickup_config(), ast_hangup(), ast_log, ast_pickup_call(), rtp_direct_media_data::chan, ast_sip_session::channel, ast_sip_session::exten, LOG_ERROR, and ast_features_pickup_config::pickupexten.

3133 {
3134  struct ast_features_pickup_config *pickup_cfg;
3135  struct ast_channel *chan;
3136 
3137  /* Check for a to-tag to determine if this is a reinvite */
3138  if (rdata->msg_info.to->tag.slen) {
3139  /* We don't care about reinvites */
3140  return 0;
3141  }
3142 
3143  pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
3144  if (!pickup_cfg) {
3145  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
3146  return 0;
3147  }
3148 
3149  if (strcmp(session->exten, pickup_cfg->pickupexten)) {
3150  ao2_ref(pickup_cfg, -1);
3151  return 0;
3152  }
3153  ao2_ref(pickup_cfg, -1);
3154 
3155  /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
3156  * changing the channel pointer in session to a different channel. To ensure we work on the right channel
3157  * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
3158  */
3159  chan = ast_channel_ref(session->channel);
3160  if (ast_pickup_call(chan)) {
3162  } else {
3164  }
3165  /* A hangup always occurs because the pickup operation will have either failed resulting in the call
3166  * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
3167  * the channel that was replaced, which should be hung up since it is literally in limbo not connected
3168  * to anything at all.
3169  */
3170  ast_hangup(chan);
3171  ast_channel_unref(chan);
3172 
3173  return 1;
3174 }
Main Channel structure associated with a channel.
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2873
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
char exten[AST_MAX_EXTENSION]
#define ast_log
Definition: astobj2.c:42
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
#define LOG_ERROR
Definition: logger.h:285
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:200
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2523
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2862
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
Configuration relating to call pickup.

◆ chan_pjsip_add_hold()

static int chan_pjsip_add_hold ( const char *  chan_uid)
static

Add a channel ID to the list of PJSIP channels on hold.

Parameters
chan_uid- Unique ID of the channel being put into the hold list
Return values
0Channel has been added to or was already in the hold list
-1Failed to add channel to the hold list

Definition at line 1133 of file chan_pjsip.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_find, ao2_link, ast_copy_string(), NULL, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by chan_pjsip_indicate().

1134 {
1135  RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1136 
1137  hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1138  if (hold_uid) {
1139  /* Device is already on hold. Nothing to do. */
1140  return 0;
1141  }
1142 
1143  /* Device wasn't in hold list already. Create a new one. */
1144  hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
1146  if (!hold_uid) {
1147  return -1;
1148  }
1149 
1150  ast_copy_string(hold_uid, chan_uid, strlen(chan_uid) + 1);
1151 
1152  if (ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
1153  return -1;
1154  }
1155 
1156  return 0;
1157 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
#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:851
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1123
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#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 ao2_link(container, obj)
Definition: astobj2.h:1549

◆ chan_pjsip_answer()

static int chan_pjsip_answer ( struct ast_channel ast)
static

Function called by core when we should answer a PJSIP session.

Definition at line 731 of file chan_pjsip.c.

References answer(), ao2_bump, ao2_ref, ast_channel_lock, ast_channel_name(), ast_channel_tech_pvt(), ast_channel_unlock, ast_log, ast_setstate(), ast_sip_push_task_wait_serializer(), AST_STATE_UP, ast_trace_get_indent, ast_sip_session::channel, answer_data::indent, ast_sip_session::inv_session, LOG_ERROR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, ast_sip_session::serializer, rtp_direct_media_data::session, ast_sip_channel_pvt::session, and answer_data::session.

Referenced by chan_pjsip_pvt_dtor().

732 {
734  struct ast_sip_session *session;
735  struct answer_data ans_data = { 0, };
736  int res;
737  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
738 
739  if (ast_channel_state(ast) == AST_STATE_UP) {
740  SCOPE_EXIT_RTN_VALUE(0, "Already up\n");
741  return 0;
742  }
743 
745  session = ao2_bump(channel->session);
746 
747 #ifdef HAVE_PJSIP_INV_SESSION_REF
748  if (pjsip_inv_add_ref(session->inv_session) != PJ_SUCCESS) {
749  ast_log(LOG_ERROR, "Couldn't increase the session reference counter\n");
750  ao2_ref(session, -1);
751  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't increase the session reference counter\n");
752  }
753 #endif
754 
755  /* the answer task needs to be pushed synchronously otherwise a race condition
756  can occur between this thread and bridging (specifically when native bridging
757  attempts to do direct media) */
758  ast_channel_unlock(ast);
759  ans_data.session = session;
760  ans_data.indent = ast_trace_get_indent();
761  res = ast_sip_push_task_wait_serializer(session->serializer, answer, &ans_data);
762  if (res) {
763  if (res == -1) {
764  ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
765  ast_channel_name(session->channel));
766 #ifdef HAVE_PJSIP_INV_SESSION_REF
767  pjsip_inv_dec_ref(session->inv_session);
768 #endif
769  }
770  ao2_ref(session, -1);
771  ast_channel_lock(ast);
772  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
773  }
774  ao2_ref(session, -1);
775  ast_channel_lock(ast);
776 
778 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
void * ast_channel_tech_pvt(const struct ast_channel *chan)
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
struct pjsip_inv_session * inv_session
#define ast_trace_get_indent()
Definition: logger.h:867
A structure describing a SIP session.
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
unsigned long indent
Definition: chan_pjsip.c:677
static struct ast_mansession session
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:5065
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
static int answer(void *data)
Definition: chan_pjsip.c:680
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2838
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
const char * ast_channel_name(const struct ast_channel *chan)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7325
struct ast_sip_session * session
Definition: chan_pjsip.c:676

◆ chan_pjsip_call()

static int chan_pjsip_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
)
static

Function called by core to actually start calling a remote party.

Definition at line 2452 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_channel_tech_pvt(), ast_log, ast_sip_push_task(), ast_sip_session_get_name(), ast_str_tmp, ast_stream_topology_to_str(), call(), LOG_WARNING, ast_sip_session::pending_media_state, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, ast_sip_session::serializer, ast_sip_channel_pvt::session, and ast_sip_session_media_state::topology.

Referenced by chan_pjsip_pvt_dtor().

2453 {
2455  SCOPE_ENTER(1, "%s Topology: %s\n", ast_sip_session_get_name(channel->session),
2457 
2458  ao2_ref(channel, +1);
2459  if (ast_sip_push_task(channel->session->serializer, call, channel)) {
2460  ast_log(LOG_WARNING, "Error attempting to place outbound call to '%s'\n", dest);
2461  ao2_cleanup(channel);
2462  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
2463  }
2464 
2465  SCOPE_EXIT_RTN_VALUE(0, "'call' task pushed\n");
2466 }
struct ast_sip_session_media_state * pending_media_state
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
static int call(void *data)
Definition: chan_pjsip.c:2425
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_log
Definition: astobj2.c:42
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:921
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_taskprocessor * serializer
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_stream_topology * topology
The media stream topology.

◆ chan_pjsip_cng_tone_detected()

static struct ast_frame* chan_pjsip_cng_tone_detected ( struct ast_channel ast,
struct ast_sip_session session,
struct ast_frame f 
)
static

Internal helper function called when CNG tone is detected.

Definition at line 781 of file chan_pjsip.c.

References ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_name(), ast_channel_unlock, ast_dsp_free(), ast_dsp_get_features(), ast_dsp_set_features(), ast_exists_extension(), ast_frfree, ast_log, ast_null_frame, ast_verb, ast_sip_session::dsp, DSP_FEATURE_FAX_DETECT, exists(), LOG_ERROR, LOG_NOTICE, NULL, pbx_builtin_setvar_helper(), S_COR, and S_OR.

Referenced by chan_pjsip_read_stream().

783 {
784  const char *target_context;
785  int exists;
786  int dsp_features;
787 
788  dsp_features = ast_dsp_get_features(session->dsp);
789  dsp_features &= ~DSP_FEATURE_FAX_DETECT;
790  if (dsp_features) {
791  ast_dsp_set_features(session->dsp, dsp_features);
792  } else {
793  ast_dsp_free(session->dsp);
794  session->dsp = NULL;
795  }
796 
797  /* If already executing in the fax extension don't do anything */
798  if (!strcmp(ast_channel_exten(ast), "fax")) {
799  return f;
800  }
801 
802  target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
803 
804  /*
805  * We need to unlock the channel here because ast_exists_extension has the
806  * potential to start and stop an autoservice on the channel. Such action
807  * is prone to deadlock if the channel is locked.
808  *
809  * ast_async_goto() has its own restriction on not holding the channel lock.
810  */
811  ast_channel_unlock(ast);
812  ast_frfree(f);
813  f = &ast_null_frame;
814  exists = ast_exists_extension(ast, target_context, "fax", 1,
815  S_COR(ast_channel_caller(ast)->id.number.valid,
816  ast_channel_caller(ast)->id.number.str, NULL));
817  if (exists) {
818  ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n",
819  ast_channel_name(ast));
820  pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
821  if (ast_async_goto(ast, target_context, "fax", 1)) {
822  ast_log(LOG_ERROR, "Failed to async goto '%s' into fax extension in '%s'\n",
823  ast_channel_name(ast), target_context);
824  }
825  } else {
826  ast_log(LOG_NOTICE, "FAX CNG detected on '%s' but no fax extension in '%s'\n",
827  ast_channel_name(ast), target_context);
828  }
829 
830  /* It's possible for a masquerade to have occurred when doing the ast_async_goto resulting in
831  * the channel on the session having changed. Since we need to return with the original channel
832  * locked we lock the channel that was passed in and not session->channel.
833  */
834  ast_channel_lock(ast);
835 
836  return f;
837 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2837
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_logic.c:124
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1744
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:455
Number structure.
Definition: app_followme.c:154
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:1738
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4170
const char * ast_channel_exten(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2838
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1729
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#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
const char * ast_channel_name(const struct ast_channel *chan)
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:7002
#define ast_frfree(fr)
const char * ast_channel_context(const struct ast_channel *chan)
const char * ast_channel_macrocontext(const struct ast_channel *chan)

◆ chan_pjsip_devicestate()

static int chan_pjsip_devicestate ( const char *  data)
static

Function called to get the device state of an endpoint.

Definition at line 1190 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_channel_snapshot_get_latest(), AST_DEVICE_BUSY, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_aggregate_add(), ast_devstate_aggregate_init(), ast_devstate_aggregate_result(), ast_endpoint_get_resource(), ast_endpoint_get_tech(), ast_endpoint_latest_snapshot(), AST_ENDPOINT_OFFLINE, AST_ENDPOINT_ONLINE, ast_sip_get_sorcery(), ast_sorcery_retrieve_by_id(), AST_STATE_BUSY, ast_state_chan2dev(), AST_STATE_RING, AST_STATE_UP, ast_channel_snapshot::base, chan_pjsip_get_hold(), ast_devstate_aggregate::inuse, NULL, RAII_VAR, ast_channel_snapshot::state, state, and ast_channel_snapshot_base::uniqueid.

Referenced by chan_pjsip_pvt_dtor().

1191 {
1192  RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", data), ao2_cleanup);
1194  RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, NULL, ao2_cleanup);
1195  struct ast_devstate_aggregate aggregate;
1196  int num, inuse = 0;
1197 
1198  if (!endpoint) {
1199  return AST_DEVICE_INVALID;
1200  }
1201 
1202  endpoint_snapshot = ast_endpoint_latest_snapshot(ast_endpoint_get_tech(endpoint->persistent),
1203  ast_endpoint_get_resource(endpoint->persistent));
1204 
1205  if (!endpoint_snapshot) {
1206  return AST_DEVICE_INVALID;
1207  }
1208 
1209  if (endpoint_snapshot->state == AST_ENDPOINT_OFFLINE) {
1210  state = AST_DEVICE_UNAVAILABLE;
1211  } else if (endpoint_snapshot->state == AST_ENDPOINT_ONLINE) {
1212  state = AST_DEVICE_NOT_INUSE;
1213  }
1214 
1215  if (!endpoint_snapshot->num_channels) {
1216  return state;
1217  }
1218 
1219  ast_devstate_aggregate_init(&aggregate);
1220 
1221  for (num = 0; num < endpoint_snapshot->num_channels; num++) {
1222  struct ast_channel_snapshot *snapshot;
1223 
1224  snapshot = ast_channel_snapshot_get_latest(endpoint_snapshot->channel_ids[num]);
1225  if (!snapshot) {
1226  continue;
1227  }
1228 
1229  if (chan_pjsip_get_hold(snapshot->base->uniqueid)) {
1231  } else {
1232  ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
1233  }
1234 
1235  if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
1236  (snapshot->state == AST_STATE_BUSY)) {
1237  inuse++;
1238  }
1239 
1240  ao2_ref(snapshot, -1);
1241  }
1242 
1243  if (endpoint->devicestate_busy_at && (inuse == endpoint->devicestate_busy_at)) {
1244  state = AST_DEVICE_BUSY;
1245  } else if (ast_devstate_aggregate_result(&aggregate) != AST_DEVICE_INVALID) {
1246  state = ast_devstate_aggregate_result(&aggregate);
1247  }
1248 
1249  return state;
1250 }
enum sip_cc_notify_state state
Definition: chan_sip.c:956
ast_device_state
Device States.
Definition: devicestate.h:52
struct ast_channel_snapshot_base * base
const char * ast_endpoint_get_tech(const struct ast_endpoint *endpoint)
Gets the technology of the given endpoint.
struct ast_endpoint_snapshot * ast_endpoint_latest_snapshot(const char *tech, const char *resource)
Retrieve the most recent snapshot for the endpoint with the given name.
Structure representing a snapshot of channel state.
const ast_string_field uniqueid
#define NULL
Definition: resample.c:96
const char * ast_endpoint_get_resource(const struct ast_endpoint *endpoint)
Gets the resource name of the given endpoint.
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
Definition: devicestate.c:663
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:1850
#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:851
#define ao2_ref(o, delta)
Definition: astobj2.h:464
enum ast_device_state ast_state_chan2dev(enum ast_channel_state chanstate)
Convert channel state to devicestate.
Definition: devicestate.c:242
An entity with which Asterisk communicates.
Definition: res_pjsip.h:807
A snapshot of an endpoint&#39;s state.
void ast_devstate_aggregate_add(struct ast_devstate_aggregate *agg, enum ast_device_state state)
Add a device state to the aggregate device state.
Definition: devicestate.c:636
static int chan_pjsip_get_hold(const char *chan_uid)
Determine whether a channel ID is in the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1177
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
Definition: devicestate.c:630
enum ast_channel_state state
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
You shouldn&#39;t care about the contents of this struct.
Definition: devicestate.h:230

◆ chan_pjsip_digit_begin()

static int chan_pjsip_digit_begin ( struct ast_channel ast,
char  digit 
)
static

Function called by core to start a DTMF digit.

Definition at line 2195 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ast_channel_tech_pvt(), AST_MEDIA_TYPE_AUDIO, AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_NONE, ast_rtp_instance_dtmf_begin(), ast_rtp_instance_dtmf_mode_get(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_NONE, AST_SIP_DTMF_RFC_4733, ast_sip_session_media_state::default_session, ast_sip_session::dtmf, ast_sip_session_media::rtp, and ast_sip_channel_pvt::session.

Referenced by chan_pjsip_pvt_dtor().

2196 {
2198  struct ast_sip_session_media *media;
2199 
2201 
2202  switch (channel->session->dtmf) {
2203  case AST_SIP_DTMF_RFC_4733:
2204  if (!media || !media->rtp) {
2205  return 0;
2206  }
2207 
2209  break;
2210  case AST_SIP_DTMF_AUTO:
2211  if (!media || !media->rtp) {
2212  return 0;
2213  }
2214 
2216  return -1;
2217  }
2218 
2220  break;
2222  if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) {
2223  return 0;
2224  }
2226  break;
2227  case AST_SIP_DTMF_NONE:
2228  break;
2229  case AST_SIP_DTMF_INBAND:
2230  return -1;
2231  default:
2232  break;
2233  }
2234 
2235  return 0;
2236 }
char digit
void * ast_channel_tech_pvt(const struct ast_channel *chan)
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
struct ast_sip_session_media_state * active_media_state
enum ast_sip_dtmf_mode dtmf
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2081
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
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

◆ chan_pjsip_digit_end()

static int chan_pjsip_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)
static

Function called by core to stop a DTMF digit.

Definition at line 2318 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ao2_cleanup, ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_log, AST_MEDIA_TYPE_AUDIO, AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_NONE, ast_rtp_instance_dtmf_end_with_duration(), ast_rtp_instance_dtmf_mode_get(), 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(), ast_sip_session_media_state::default_session, ast_sip_session::dtmf, info_dtmf_data_alloc(), ast_sip_session::inv_session, LOG_ERROR, LOG_WARNING, ast_sip_session_media::rtp, ast_sip_session::serializer, ast_sip_channel_pvt::session, info_dtmf_data::session, and transmit_info_dtmf().

Referenced by chan_pjsip_pvt_dtor().

2319 {
2321  struct ast_sip_session_media *media;
2322 
2323  if (!channel || !channel->session) {
2324  /* This happens when the channel is hungup while a DTMF digit is playing. See ASTERISK-28086 */
2325  ast_debug(3, "Channel %s disappeared while calling digit_end\n", ast_channel_name(ast));
2326  return -1;
2327  }
2328 
2330 
2331  switch (channel->session->dtmf) {
2333  {
2334  if (!media || !media->rtp) {
2335  return 0;
2336  }
2337 
2339  ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));
2341  break;
2342  }
2343  /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */
2344  ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 NOT negotiated using INFO instead.\n", ast_channel_name(ast));
2345  }
2346 
2347  case AST_SIP_DTMF_INFO:
2348  {
2349  struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
2350 
2351  if (!dtmf_data) {
2352  return -1;
2353  }
2354 
2355 #ifdef HAVE_PJSIP_INV_SESSION_REF
2356  if (pjsip_inv_add_ref(dtmf_data->session->inv_session) != PJ_SUCCESS) {
2357  ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
2358  ao2_cleanup(dtmf_data);
2359  return -1;
2360  }
2361 #endif
2362 
2363  if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
2364  ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
2365 #ifdef HAVE_PJSIP_INV_SESSION_REF
2366  pjsip_inv_dec_ref(dtmf_data->session->inv_session);
2367 #endif
2368  ao2_cleanup(dtmf_data);
2369  return -1;
2370  }
2371  break;
2372  }
2373  case AST_SIP_DTMF_RFC_4733:
2374  if (!media || !media->rtp) {
2375  return 0;
2376  }
2377 
2379  break;
2380  case AST_SIP_DTMF_AUTO:
2381  if (!media || !media->rtp) {
2382  return 0;
2383  }
2384 
2386  return -1;
2387  }
2388 
2390  break;
2391  case AST_SIP_DTMF_NONE:
2392  break;
2393  case AST_SIP_DTMF_INBAND:
2394  return -1;
2395  }
2396 
2397  return 0;
2398 }
char digit
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
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.
unsigned int duration
Definition: chan_pjsip.c:2241
Definition: muted.c:95
struct pjsip_inv_session * inv_session
struct ast_sip_session_media_state * active_media_state
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
static int transmit_info_dtmf(void *data)
Definition: chan_pjsip.c:2263
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
enum ast_sip_dtmf_mode dtmf
static struct info_dtmf_data * info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
Definition: chan_pjsip.c:2250
A structure containing SIP session media information.
struct ast_sip_session * session
Definition: chan_pjsip.c:2239
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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
int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
Definition: rtp_engine.c:2109

◆ chan_pjsip_fixup()

static int chan_pjsip_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Function called by core to change the underlying owner channel.

Definition at line 1061 of file chan_pjsip.c.

References ast_channel_tech_pvt(), ast_channel_uniqueid(), ast_sip_session::channel, ast_sip_channel_pvt::session, and set_channel_on_rtp_instance().

Referenced by chan_pjsip_pvt_dtor().

1062 {
1064 
1065  if (channel->session->channel != oldchan) {
1066  return -1;
1067  }
1068 
1069  /*
1070  * The masquerade has suspended the channel's session
1071  * serializer so we can safely change it outside of
1072  * the serializer thread.
1073  */
1074  channel->session->channel = newchan;
1075 
1077 
1078  return 0;
1079 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:492
struct ast_channel * channel
const char * ast_channel_uniqueid(const struct ast_channel *chan)

◆ chan_pjsip_get_codec()

static void chan_pjsip_get_codec ( struct ast_channel chan,
struct ast_format_cap result 
)
static

Function called by RTP engine to get peer capabilities.

Definition at line 242 of file chan_pjsip.c.

References ast_channel_name(), ast_channel_nativeformats(), ast_format_cap_append_from_cap(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, AST_MEDIA_TYPE_UNKNOWN, ast_str_tmp, SCOPE_ENTER, and SCOPE_EXIT_RTN.

243 {
244  SCOPE_ENTER(1, "%s Native formats %s\n", ast_channel_name(chan),
247  SCOPE_EXIT_RTN();
248 }
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define SCOPE_EXIT_RTN(...)
Definition: logger.h:876
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
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

◆ chan_pjsip_get_hold()

static int chan_pjsip_get_hold ( const char *  chan_uid)
static

Determine whether a channel ID is in the list of PJSIP channels on hold.

Parameters
chan_uid- Channel being checked
Return values
0The channel is not in the hold list
1The channel is in the hold list

Definition at line 1177 of file chan_pjsip.c.

References ao2_cleanup, ao2_find, NULL, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by chan_pjsip_devicestate().

1178 {
1179  RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1180 
1181  hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1182  if (!hold_uid) {
1183  return 0;
1184  }
1185 
1186  return 1;
1187 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define NULL
Definition: resample.c:96
#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:851
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1123
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ chan_pjsip_get_rtp_peer()

static enum ast_rtp_glue_result chan_pjsip_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
)
static

Function called by RTP engine to get local audio RTP peer.

Definition at line 169 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ao2_ref, ast_assert, ast_channel_tech_pvt(), AST_MEDIA_TYPE_AUDIO, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, AST_SIP_MEDIA_ENCRYPT_NONE, ast_sip_session_get_datastore(), ast_sip_session_media_state::default_session, ast_sip_endpoint_media_configuration::direct_media, ast_sip_direct_media_configuration::enabled, ast_sip_media_rtp_configuration::encryption, ast_sip_session::endpoint, ast_sip_endpoint::media, NULL, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, and ast_sip_channel_pvt::session.

170 {
172  struct ast_sip_endpoint *endpoint;
173  struct ast_datastore *datastore;
174  struct ast_sip_session_media *media;
175 
176  if (!channel || !channel->session) {
178  }
179 
180  /* XXX Getting the first RTP instance for direct media related stuff seems just
181  * absolutely wrong. But the native RTP bridge knows no other method than single-stream
182  * for direct media. So this is the best we can do.
183  */
185  if (!media || !media->rtp) {
187  }
188 
189  datastore = ast_sip_session_get_datastore(channel->session, "t38");
190  if (datastore) {
191  ao2_ref(datastore, -1);
193  }
194 
195  endpoint = channel->session->endpoint;
196 
197  *instance = media->rtp;
198  ao2_ref(*instance, +1);
199 
200  ast_assert(endpoint != NULL);
201  if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
203  }
204 
205  if (endpoint->media.direct_media.enabled) {
207  }
208 
210 }
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
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.
#define ast_assert(a)
Definition: utils.h:650
Definition: muted.c:95
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:761
struct ast_sip_session_media_state * active_media_state
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:759
#define ao2_ref(o, delta)
Definition: astobj2.h:464
An entity with which Asterisk communicates.
Definition: res_pjsip.h:807
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:706
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.

◆ chan_pjsip_get_uniqueid()

static const char * chan_pjsip_get_uniqueid ( struct ast_channel ast)
static

Definition at line 1294 of file chan_pjsip.c.

References ast_channel_tech_pvt(), ast_copy_pj_str(), ast_threadstorage_get(), ast_sip_session::inv_session, ast_sip_channel_pvt::session, UNIQUEID_BUFSIZE, and uniqueid_threadbuf.

Referenced by chan_pjsip_pvt_dtor().

1295 {
1298 
1299  if (!uniqueid) {
1300  return "";
1301  }
1302 
1303  ast_copy_pj_str(uniqueid, &channel->session->inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
1304 
1305  return uniqueid;
1306 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define UNIQUEID_BUFSIZE
Definition: chan_pjsip.c:76
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
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:5087
struct pjsip_inv_session * inv_session
static struct ast_threadstorage uniqueid_threadbuf
Definition: chan_pjsip.c:75

◆ chan_pjsip_get_vrtp_peer()

static enum ast_rtp_glue_result chan_pjsip_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
)
static

Function called by RTP engine to get local video RTP peer.

Definition at line 213 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ao2_ref, ast_assert, ast_channel_tech_pvt(), AST_MEDIA_TYPE_VIDEO, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_SIP_MEDIA_ENCRYPT_NONE, ast_sip_session_media_state::default_session, ast_sip_media_rtp_configuration::encryption, ast_sip_session::endpoint, ast_sip_endpoint::media, NULL, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, and ast_sip_channel_pvt::session.

214 {
216  struct ast_sip_endpoint *endpoint;
217  struct ast_sip_session_media *media;
218 
219  if (!channel || !channel->session) {
221  }
222 
224  if (!media || !media->rtp) {
226  }
227 
228  endpoint = channel->session->endpoint;
229 
230  *instance = media->rtp;
231  ao2_ref(*instance, +1);
232 
233  ast_assert(endpoint != NULL);
234  if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
236  }
237 
239 }
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
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.
#define ast_assert(a)
Definition: utils.h:650
Definition: muted.c:95
#define NULL
Definition: resample.c:96
struct ast_sip_session_media_state * active_media_state
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:759
#define ao2_ref(o, delta)
Definition: astobj2.h:464
An entity with which Asterisk communicates.
Definition: res_pjsip.h:807
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:706
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.

◆ chan_pjsip_hangup()

static int chan_pjsip_hangup ( struct ast_channel ast)
static

Function called by core to hang up a PJSIP session.

Definition at line 2583 of file chan_pjsip.c.

References ao2_cleanup, ast_channel_hangupcause(), ast_channel_name(), ast_channel_tech_pvt(), ast_log, ast_sip_push_task(), ast_sip_session::channel, clear_session_and_channel(), hangup(), hangup_cause2sip(), hangup_data_alloc(), LOG_WARNING, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, ast_sip_session::serializer, and ast_sip_channel_pvt::session.

Referenced by chan_pjsip_pvt_dtor().

2584 {
2586  int cause;
2587  struct hangup_data *h_data;
2588  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2589 
2590  if (!channel || !channel->session) {
2591  SCOPE_EXIT_RTN_VALUE(-1, "No channel or session\n");
2592  }
2593 
2595  h_data = hangup_data_alloc(cause, ast);
2596 
2597  if (!h_data) {
2598  goto failure;
2599  }
2600 
2601  if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
2602  ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
2603  goto failure;
2604  }
2605 
2606  SCOPE_EXIT_RTN_VALUE(0, "Cause: %d\n", cause);
2607 
2608 failure:
2609  /* Go ahead and do our cleanup of the session and channel even if we're not going
2610  * to be able to send our SIP request/response
2611  */
2612  clear_session_and_channel(channel->session, ast);
2613  ao2_cleanup(channel);
2614  ao2_cleanup(h_data);
2615 
2616  SCOPE_EXIT_RTN_VALUE(-1, "Cause: %d\n", cause);
2617 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
static int hangup_cause2sip(int cause)
Internal function which translates from Asterisk cause codes to SIP response codes.
Definition: chan_pjsip.c:2469
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
static int hangup(void *data)
Definition: chan_pjsip.c:2550
#define ast_log
Definition: astobj2.c:42
struct ast_channel * channel
struct ast_taskprocessor * serializer
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
static struct hangup_data * hangup_data_alloc(int cause, struct ast_channel *chan)
Definition: chan_pjsip.c:2528
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast)
Clear a channel from a session along with its PVT.
Definition: chan_pjsip.c:2543

◆ chan_pjsip_incoming_ack()

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

Definition at line 3290 of file chan_pjsip.c.

References AST_CONTROL_SRCCHANGE, ast_queue_control(), ast_sip_session_get_name(), ast_trace, ast_sip_session::channel, ast_sip_endpoint_media_configuration::direct_media, ast_sip_direct_media_configuration::enabled, ast_sip_session::endpoint, ast_sip_endpoint::media, SCOPE_ENTER, and SCOPE_EXIT_RTN_VALUE.

3291 {
3292  SCOPE_ENTER(1, "%s Method: %.*s Status: %d After Media\n", ast_sip_session_get_name(session),
3293  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr,
3294  rdata->msg_info.msg->line.status.code);
3295 
3296  if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
3297  if (session->endpoint->media.direct_media.enabled && session->channel) {
3298  ast_trace(1, "%s Method: %.*s Queueing SRCCHANGE\n", ast_sip_session_get_name(session),
3299  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr);
3301  }
3302  }
3304 }
struct ast_sip_endpoint * endpoint
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1227
#define ast_trace(__level,...)
Definition: logger.h:866
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:761
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
struct ast_channel * channel
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877

◆ chan_pjsip_incoming_request()

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

Function called when a request is received on the session.

Definition at line 3077 of file chan_pjsip.c.

References ao2_cleanup, ast_calloc, ast_log, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_name(), ast_sip_session_send_response(), ast_sip_session_terminate(), AST_STATE_RING, chan_pjsip_new(), ast_sip_session::channel, ast_sip_session::defer_terminate, ast_sip_session::exten, ast_sip_session::inv_session, transport_info_data::local_addr, LOG_ERROR, NULL, RAII_VAR, transport_info_data::remote_addr, SCOPE_ENTER, and SCOPE_EXIT_RTN_VALUE.

3078 {
3079  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
3080  struct transport_info_data *transport_data;
3081  pjsip_tx_data *packet = NULL;
3082  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
3083 
3084  if (session->channel) {
3085  SCOPE_EXIT_RTN_VALUE(0, "Already have channel\n");
3086  }
3087 
3088  /* Check for a to-tag to determine if this is a reinvite */
3089  if (rdata->msg_info.to->tag.slen) {
3090  /* Weird case. We've received a reinvite but we don't have a channel. The most
3091  * typical case for this happening is that a blind transfer fails, and so the
3092  * transferer attempts to reinvite himself back into the call. We already got
3093  * rid of that channel, and the other side of the call is unrecoverable.
3094  *
3095  * We treat this as a failure, so our best bet is to just hang this call
3096  * up and not create a new channel. Clearing defer_terminate here ensures that
3097  * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
3098  */
3099  session->defer_terminate = 0;
3100  ast_sip_session_terminate(session, 400);
3101  SCOPE_EXIT_RTN_VALUE(-1, "Reinvite without channel\n");
3102  }
3103 
3104  datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
3105  if (!datastore) {
3106  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create datastore\n");
3107  }
3108 
3109  transport_data = ast_calloc(1, sizeof(*transport_data));
3110  if (!transport_data) {
3111  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create transport_data\n");
3112  }
3113  pj_sockaddr_cp(&transport_data->local_addr, &rdata->tp_info.transport->local_addr);
3114  pj_sockaddr_cp(&transport_data->remote_addr, &rdata->pkt_info.src_addr);
3115  datastore->data = transport_data;
3116  ast_sip_session_add_datastore(session, datastore);
3117 
3118  if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
3119  if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS
3120  && packet) {
3121  ast_sip_session_send_response(session, packet);
3122  }
3123 
3124  ast_log(LOG_ERROR, "Failed to allocate new PJSIP channel on incoming SIP INVITE\n");
3125  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create channel\n");
3126  }
3127  /* channel gets created on incoming request, but we wait to call start
3128  so other supplements have a chance to run */
3130 }
pj_sockaddr local_addr
Our address that received the request.
Definition: chan_pjsip.h:34
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
unsigned int defer_terminate
static struct ast_channel * chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
Function called to create a new PJSIP Asterisk channel.
Definition: chan_pjsip.c:545
static struct ast_datastore_info transport_info
Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel...
Definition: chan_pjsip.c:259
Structure for a data store object.
Definition: datastore.h:68
char exten[AST_MAX_EXTENSION]
#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_log
Definition: astobj2.c:42
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
#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:851
struct ast_channel * channel
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
pj_sockaddr remote_addr
The address that sent the request.
Definition: chan_pjsip.h:32
#define LOG_ERROR
Definition: logger.h:285
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.

◆ chan_pjsip_incoming_response()

static void chan_pjsip_incoming_response ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
)
static

Function called when a response is received on the session.

Definition at line 3223 of file chan_pjsip.c.

References ast_alloca, ast_control_pvt_cause_code::ast_cause, ast_channel_hangupcause_hash_set(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_name(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RINGING, ast_copy_string(), ast_queue_control(), ast_queue_control_data(), ast_setstate(), ast_sip_session_get_name(), AST_STATE_RINGING, AST_STATE_UP, ast_trace, ast_control_pvt_cause_code::chan_name, ast_sip_session::channel, ast_control_pvt_cause_code::code, ast_sip_session::endpoint, hangup_sip2cause(), ast_sip_endpoint::ignore_183_without_sdp, SCOPE_ENTER, and SCOPE_EXIT_RTN.

3224 {
3225  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3226  struct ast_control_pvt_cause_code *cause_code;
3227  int data_size = sizeof(*cause_code);
3228  SCOPE_ENTER(1, "%s Method: %.*s Status: %d\n", ast_sip_session_get_name(session),
3229  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3230 
3231  if (!session->channel) {
3232  SCOPE_EXIT_RTN("No channel\n");
3233  }
3234 
3235  /* Build and send the tech-specific cause information */
3236  /* size of the string making up the cause code is "SIP " number + " " + reason length */
3237  data_size += 4 + 4 + pj_strlen(&status.reason);
3238  cause_code = ast_alloca(data_size);
3239  memset(cause_code, 0, data_size);
3240 
3242 
3243  snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
3244  (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
3245 
3246  cause_code->ast_cause = hangup_sip2cause(status.code);
3247  ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
3248  ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
3249 
3250  switch (status.code) {
3251  case 180:
3252  ast_trace(1, "%s Method: %.*s Status: %d Queueing RINGING\n", ast_sip_session_get_name(session),
3253  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3255  ast_channel_lock(session->channel);
3256  if (ast_channel_state(session->channel) != AST_STATE_UP) {
3258  }
3259  ast_channel_unlock(session->channel);
3260  break;
3261  case 183:
3262  if (session->endpoint->ignore_183_without_sdp) {
3263  pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3264  if (sdp && sdp->body.ptr) {
3265  ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS with SDP\n", ast_sip_session_get_name(session),
3266  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3268  }
3269  } else {
3270  ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS without SDP\n", ast_sip_session_get_name(session),
3271  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3273  }
3274  break;
3275  case 200:
3276  ast_trace(1, "%s Method: %.*s Status: %d Queueing ANSWER\n", ast_sip_session_get_name(session),
3277  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3278 
3280  break;
3281  default:
3282  ast_trace(1, "%s Method: %.*s Status: %d Ignored\n", ast_sip_session_get_name(session),
3283  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3284  break;
3285  }
3286 
3287  SCOPE_EXIT_RTN();
3288 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
struct ast_sip_endpoint * endpoint
char chan_name[AST_CHANNEL_NAME]
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1227
#define ast_trace(__level,...)
Definition: logger.h:866
unsigned int ignore_183_without_sdp
Definition: res_pjsip.h:896
ast_channel_state
ast_channel states
Definition: channelstate.h:35
static int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_pjsip.c:2942
struct ast_channel * channel
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN(...)
Definition: logger.h:876
#define ast_channel_unlock(chan)
Definition: channel.h:2838
#define AST_CHANNEL_NAME
Definition: channel.h:172
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
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)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7325
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1234
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
Definition: channel.c:4340
jack_status_t status
Definition: app_jack.c:146

◆ chan_pjsip_indicate()

static int chan_pjsip_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
)
static

Function called by core to ask the channel to indicate some sort of condition.

Definition at line 1640 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ao2_bump, ao2_cleanup, ao2_ref, ast_assert, ast_channel_get_device_name(), ast_channel_lock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_tech_pvt(), ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE, AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_DEVICE_ONHOLD, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_devstate_changed_literal(), ast_format_cap_iscompatible_format(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_h264, ast_format_h265, ast_format_vp8, ast_format_vp9, AST_FRAME_CONTROL, ast_frame_subclass2str(), ast_log, AST_MEDIA_TYPE_VIDEO, ast_moh_start(), ast_moh_stop(), ast_rtp_instance_write(), ast_sip_push_task(), ast_sip_session_suspend(), ast_sip_session_unsuspend(), ast_sorcery_object_get_id(), AST_STATE_RING, AST_STATE_UP, AST_T38_REQUEST_PARMS, ast_test_suite_event_notify, AST_VECTOR_GET, AST_VECTOR_SIZE, chan_pjsip_add_hold(), chan_pjsip_remove_hold(), ast_sip_session::endpoint, ast_frame::frametype, handle_topology_request_change(), ast_sip_endpoint::inband_progress, indicate(), indicate_data_alloc(), ast_frame_subclass::integer, ast_sip_session::inv_session, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_sip_endpoint::media, ast_sip_session::moh_passthrough, NULL, remote_send_hold(), remote_send_unhold(), ast_control_t38_parameters::request_response, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, ast_sip_session::serializer, ast_sip_channel_pvt::session, indicate_data::session, ast_frame::subclass, T38_PEER_REINVITE, ast_sip_session::t38state, transmit_info_with_vidupdate(), ast_sip_session_media::type, update_connected_line_information(), and ast_sip_endpoint_media_configuration::webrtc.

Referenced by chan_pjsip_pvt_dtor().

1641 {
1643  struct ast_sip_session_media *media;
1644  int response_code = 0;
1645  int res = 0;
1646  char *device_buf;
1647  size_t device_buf_size;
1648  int i;
1649  const struct ast_stream_topology *topology;
1650  struct ast_frame f = { .frametype = AST_FRAME_CONTROL, .subclass = { .integer = condition } };
1651  char subclass[40] = "";
1652  SCOPE_ENTER(1, "%s Handling %s\n", ast_channel_name(ast),
1653  ast_frame_subclass2str(&f, subclass, sizeof(subclass), NULL, 0));
1654 
1655  switch (condition) {
1656  case AST_CONTROL_RINGING:
1657  if (ast_channel_state(ast) == AST_STATE_RING) {
1658  if (channel->session->endpoint->inband_progress ||
1659  (channel->session->inv_session && channel->session->inv_session->neg &&
1660  pjmedia_sdp_neg_get_state(channel->session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE)) {
1661  response_code = 183;
1662  res = -1;
1663  } else {
1664  response_code = 180;
1665  }
1666  } else {
1667  res = -1;
1668  }
1670  break;
1671  case AST_CONTROL_BUSY:
1672  if (ast_channel_state(ast) != AST_STATE_UP) {
1673  response_code = 486;
1674  } else {
1675  res = -1;
1676  }
1677  break;
1679  if (ast_channel_state(ast) != AST_STATE_UP) {
1680  response_code = 503;
1681  } else {
1682  res = -1;
1683  }
1684  break;
1686  if (ast_channel_state(ast) != AST_STATE_UP) {
1687  response_code = 484;
1688  } else {
1689  res = -1;
1690  }
1691  break;
1693  if (ast_channel_state(ast) != AST_STATE_UP) {
1694  response_code = 100;
1695  } else {
1696  res = -1;
1697  }
1698  break;
1699  case AST_CONTROL_PROGRESS:
1700  if (ast_channel_state(ast) != AST_STATE_UP) {
1701  response_code = 183;
1702  } else {
1703  res = -1;
1704  }
1706  break;
1707  case AST_CONTROL_VIDUPDATE:
1708  for (i = 0; i < AST_VECTOR_SIZE(&channel->session->active_media_state->sessions); ++i) {
1709  media = AST_VECTOR_GET(&channel->session->active_media_state->sessions, i);
1710  if (!media || media->type != AST_MEDIA_TYPE_VIDEO) {
1711  continue;
1712  }
1713  if (media->rtp) {
1714  /* FIXME: Only use this for VP8. Additional work would have to be done to
1715  * fully support other video codecs */
1716 
1720  (channel->session->endpoint->media.webrtc &&
1722  /* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
1723  * RTP engine would provide a way to externally write/schedule RTCP
1724  * packets */
1725  struct ast_frame fr;
1727  fr.subclass.integer = AST_CONTROL_VIDUPDATE;
1728  res = ast_rtp_instance_write(media->rtp, &fr);
1729  } else {
1730  ao2_ref(channel->session, +1);
1731 #ifdef HAVE_PJSIP_INV_SESSION_REF
1732  if (pjsip_inv_add_ref(channel->session->inv_session) != PJ_SUCCESS) {
1733  ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
1734  ao2_cleanup(channel->session);
1735  } else {
1736 #endif
1738  ao2_cleanup(channel->session);
1739  }
1740 #ifdef HAVE_PJSIP_INV_SESSION_REF
1741  }
1742 #endif
1743  }
1744  ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
1745  } else {
1746  ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
1747  res = -1;
1748  }
1749  }
1750  /* XXX If there were no video streams, then this should set
1751  * res to -1
1752  */
1753  break;
1755  ao2_ref(channel->session, +1);
1756 #ifdef HAVE_PJSIP_INV_SESSION_REF
1757  if (pjsip_inv_add_ref(channel->session->inv_session) != PJ_SUCCESS) {
1758  ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
1759  ao2_cleanup(channel->session);
1760  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't increase the session reference counter\n");
1761  }
1762 #endif
1764 #ifdef HAVE_PJSIP_INV_SESSION_REF
1765  pjsip_inv_dec_ref(channel->session->inv_session);
1766 #endif
1767  ao2_cleanup(channel->session);
1768  }
1769  break;
1771  break;
1773  res = -1;
1774  break;
1776  ast_assert(datalen == sizeof(int));
1777  if (*(int *) data) {
1778  /*
1779  * Masquerade is beginning:
1780  * Wait for session serializer to get suspended.
1781  */
1782  ast_channel_unlock(ast);
1783  ast_sip_session_suspend(channel->session);
1784  ast_channel_lock(ast);
1785  } else {
1786  /*
1787  * Masquerade is complete:
1788  * Unsuspend the session serializer.
1789  */
1791  }
1792  break;
1793  case AST_CONTROL_HOLD:
1795  device_buf_size = strlen(ast_channel_name(ast)) + 1;
1796  device_buf = alloca(device_buf_size);
1797  ast_channel_get_device_name(ast, device_buf, device_buf_size);
1799  if (!channel->session->moh_passthrough) {
1800  ast_moh_start(ast, data, NULL);
1801  } else {
1803  ast_log(LOG_WARNING, "Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
1805  ao2_ref(channel->session, -1);
1806  }
1807  }
1808  break;
1809  case AST_CONTROL_UNHOLD:
1811  device_buf_size = strlen(ast_channel_name(ast)) + 1;
1812  device_buf = alloca(device_buf_size);
1813  ast_channel_get_device_name(ast, device_buf, device_buf_size);
1815  if (!channel->session->moh_passthrough) {
1816  ast_moh_stop(ast);
1817  } else {
1819  ast_log(LOG_WARNING, "Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
1821  ao2_ref(channel->session, -1);
1822  }
1823  }
1824  break;
1825  case AST_CONTROL_SRCUPDATE:
1826  break;
1827  case AST_CONTROL_SRCCHANGE:
1828  break;
1830  if (ast_channel_state(ast) != AST_STATE_UP) {
1831  response_code = 181;
1832  } else {
1833  res = -1;
1834  }
1835  break;
1837  res = 0;
1838 
1839  if (channel->session->t38state == T38_PEER_REINVITE) {
1840  const struct ast_control_t38_parameters *parameters = data;
1841 
1842  if (parameters->request_response == AST_T38_REQUEST_PARMS) {
1843  res = AST_T38_REQUEST_PARMS;
1844  }
1845  }
1846 
1847  break;
1849  topology = data;
1850  res = handle_topology_request_change(channel->session, topology);
1851  break;
1853  break;
1855  break;
1856  case -1:
1857  res = -1;
1858  break;
1859  default:
1860  ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
1861  res = -1;
1862  break;
1863  }
1864 
1865  if (response_code) {
1866  struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
1867 
1868  if (!ind_data) {
1869  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create indicate data\n");
1870  }
1871 #ifdef HAVE_PJSIP_INV_SESSION_REF
1872  if (pjsip_inv_add_ref(ind_data->session->inv_session) != PJ_SUCCESS) {
1873  ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
1874  ao2_cleanup(ind_data);
1875  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't increase the session reference counter\n");
1876  }
1877 #endif
1878  if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
1879  ast_log(LOG_NOTICE, "Cannot send response code %d to endpoint %s. Could not queue task properly\n",
1880  response_code, ast_sorcery_object_get_id(channel->session->endpoint));
1881 #ifdef HAVE_PJSIP_INV_SESSION_REF
1882  pjsip_inv_dec_ref(ind_data->session->inv_session);
1883 #endif
1884  ao2_cleanup(ind_data);
1885  res = -1;
1886  }
1887  }
1888 
1889  SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
1890 }
static int remote_send_hold(void *data)
Update local hold state to be held.
Definition: chan_pjsip.c:1537
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:196
enum ast_sip_session_t38state t38state
#define ast_channel_lock(chan)
Definition: channel.h:2837
static int indicate(void *data)
Definition: chan_pjsip.c:1349
struct ast_sip_endpoint * endpoint
static int transmit_info_with_vidupdate(void *data)
Send SIP INFO with video update request.
Definition: chan_pjsip.c:1370
void ast_sip_session_unsuspend(struct ast_sip_session *session)
Request the session serializer be unsuspended.
static int remote_send_unhold(void *data)
Update local hold state to be unheld.
Definition: chan_pjsip.c:1543
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_sip_session_suspend(struct ast_sip_session *session)
Request and wait for the session serializer to be suspended.
#define LOG_WARNING
Definition: logger.h:274
static int chan_pjsip_add_hold(const char *chan_uid)
Add a channel ID to the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1133
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
static struct indicate_data * indicate_data_alloc(struct ast_sip_session *session, int condition, int response_code, const void *frame_data, size_t datalen)
Definition: chan_pjsip.c:1324
enum ast_control_t38 request_response
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.
struct ast_sip_session * session
Definition: chan_pjsip.c:1309
#define ast_assert(a)
Definition: utils.h:650
Definition: muted.c:95
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7715
struct ast_frame_subclass subclass
unsigned int inband_progress
Definition: res_pjsip.h:858
static void chan_pjsip_remove_hold(const char *chan_uid)
Remove a channel ID from the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1164
static int update_connected_line_information(void *data)
Update connected line information.
Definition: chan_pjsip.c:1459
struct ast_sip_session_media_state * active_media_state
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
#define ao2_bump(obj)
Definition: astobj2.h:491
union ast_frame::@255 data
#define ast_log
Definition: astobj2.c:42
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
size_t datalen
Definition: chan_pjsip.c:1313
#define ao2_ref(o, delta)
Definition: astobj2.h:464
char * ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
Copy the discription of a frame&#39;s subclass into the provided string.
Definition: main/frame.c:397
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2309
struct ast_taskprocessor * serializer
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
struct ast_format * ast_format_vp9
Built-in cached vp9 format.
Definition: format_cache.c:201
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7705
struct ast_format * ast_format_h264
Built-in cached h264 format.
Definition: format_cache.c:181
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2838
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
A structure containing SIP session media information.
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
struct ast_format * ast_format_h265
Built-in cached h265 format.
Definition: format_cache.c:186
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:678
enum ast_media_type type
Media type of this session media.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
static int handle_topology_request_change(struct ast_sip_session *session, const struct ast_stream_topology *proposed)
Definition: chan_pjsip.c:1620
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:10530
Data structure associated with a single frame of data.
enum ast_frame_type frametype
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:471
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
unsigned int moh_passthrough

◆ chan_pjsip_new()

static struct ast_channel* chan_pjsip_new ( struct ast_sip_session session,
int  state,
const char *  exten,
const char *  title,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  cid_name 
)
static

Function called to create a new PJSIP Asterisk channel.

Definition at line 545 of file chan_pjsip.c.

References ast_sip_endpoint::accountcode, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_channel_adsicpe_set(), ast_channel_alloc_with_endpoint, ast_channel_caller(), ast_channel_callgroup_set(), ast_channel_dialed(), ast_channel_named_callgroups_set(), ast_channel_named_pickupgroups_set(), ast_channel_nativeformats_set(), ast_channel_pickupgroup_set(), ast_channel_priority_set(), ast_channel_rings_set(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_stream_topology(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_zone_set(), ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_empty(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_best_by_type(), ast_format_cap_get_format(), ast_get_encoded_str(), ast_get_indication_zone(), ast_hangup(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, ast_party_id_copy(), ast_sip_channel_pvt_alloc(), ast_sip_session_get_name(), ast_sorcery_object_get_id(), AST_STATE_RING, ast_strdup, ast_stream_topology_clone(), ast_stream_topology_free(), ast_stream_topology_get_count(), ast_stream_topology_get_formats(), ast_strlen_zero, buf, ast_sip_endpoint_pickup_configuration::callgroup, rtp_direct_media_data::chan, chan_idx, chan_pjsip_pvt_dtor(), ast_sip_endpoint::channel_vars, ast_sip_endpoint_media_configuration::codecs, compatible_formats_exist(), ast_sip_endpoint::context, ast_sip_session::endpoint, ast_sip_session::id, ast_sip_endpoint::language, LOG_ERROR, ast_sip_endpoint::media, ast_variable::name, ast_party_id::name, ast_sip_endpoint_pickup_configuration::named_callgroups, ast_sip_endpoint_pickup_configuration::named_pickupgroups, ast_variable::next, NULL, ast_party_id::number, ast_party_dialed::number, pbx_builtin_setvar_helper(), ast_sip_session::pending_media_state, ast_sip_endpoint::persistent, ast_sip_endpoint::pickup, ast_sip_endpoint_pickup_configuration::pickupgroup, RAII_VAR, S_COR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, set_channel_on_rtp_instance(), ast_party_name::str, ast_party_number::str, ast_party_dialed::str, ast_sip_session_media_state::topology, ast_sip_endpoint_media_configuration::topology, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, and ast_sip_endpoint::zone.

Referenced by chan_pjsip_incoming_request(), and chan_pjsip_request_with_stream_topology().

546 {
547  struct ast_channel *chan;
548  struct ast_format_cap *caps;
549  RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
551  struct ast_variable *var;
552  struct ast_stream_topology *topology;
553  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
554 
555  if (!(pvt = ao2_alloc_options(sizeof(*pvt), chan_pjsip_pvt_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK))) {
556  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt\n");
557  }
558 
560  S_COR(session->id.number.valid, session->id.number.str, ""),
561  S_COR(session->id.name.valid, session->id.name.str, ""),
562  session->endpoint->accountcode,
563  exten, session->endpoint->context,
564  assignedids, requestor, 0,
565  session->endpoint->persistent, "PJSIP/%s-%08x",
567  (unsigned) ast_atomic_fetchadd_int((int *) &chan_idx, +1));
568  if (!chan) {
569  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
570  }
571 
573 
574  if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
575  ast_channel_unlock(chan);
576  ast_hangup(chan);
577  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt channel\n");
578  }
579 
580  ast_channel_tech_pvt_set(chan, channel);
581 
585  if (!caps) {
586  ast_channel_unlock(chan);
587  ast_hangup(chan);
588  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create caps\n");
589  }
591  topology = ast_stream_topology_clone(session->endpoint->media.topology);
592  } else {
595  }
596 
597  if (!topology || !caps) {
598  ao2_cleanup(caps);
599  ast_stream_topology_free(topology);
600  ast_channel_unlock(chan);
601  ast_hangup(chan);
602  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't get caps or clone topology\n");
603  }
604 
606 
607  ast_channel_nativeformats_set(chan, caps);
608  ast_channel_set_stream_topology(chan, topology);
609 
610  if (!ast_format_cap_empty(caps)) {
611  struct ast_format *fmt;
612 
614  if (!fmt) {
615  /* Since our capabilities aren't empty, this will succeed */
616  fmt = ast_format_cap_get_format(caps, 0);
617  }
618  ast_channel_set_writeformat(chan, fmt);
620  ast_channel_set_readformat(chan, fmt);
622  ao2_ref(fmt, -1);
623  }
624 
625  ao2_ref(caps, -1);
626 
627  if (state == AST_STATE_RING) {
628  ast_channel_rings_set(chan, 1);
629  }
630 
632 
633  ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id);
634  ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id);
635 
636  if (!ast_strlen_zero(exten)) {
637  /* Set provided DNID on the new channel. */
639  }
640 
641  ast_channel_priority_set(chan, 1);
642 
645 
648 
649  if (!ast_strlen_zero(session->endpoint->language)) {
650  ast_channel_language_set(chan, session->endpoint->language);
651  }
652 
653  if (!ast_strlen_zero(session->endpoint->zone)) {
654  struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
655  if (!zone) {
656  ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
657  }
658  ast_channel_zone_set(chan, zone);
659  }
660 
661  for (var = session->endpoint->channel_vars; var; var = var->next) {
662  char buf[512];
664  var->value, buf, sizeof(buf)));
665  }
666 
668  ast_channel_unlock(chan);
669 
671 
672  SCOPE_EXIT_RTN_VALUE(chan);
673 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
struct ast_sip_endpoint_pickup_configuration pickup
Definition: res_pjsip.h:846
struct ast_variable * next
static unsigned int chan_idx
Definition: chan_pjsip.c:80
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
char * str
Subscriber phone number (Malloced)
Definition: channel.h:387
static void chan_pjsip_pvt_dtor(void *obj)
Definition: chan_pjsip.c:82
struct ast_sip_session_media_state * pending_media_state
#define ast_channel_alloc_with_endpoint(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint,...)
Definition: channel.h:1246
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:2925
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
Definition: stream.c:915
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition: channel.c:1740
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
struct ast_format_cap * codecs
Definition: res_pjsip.h:765
const ast_string_field context
Definition: res_pjsip.h:810
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
char * str
Subscriber name (Malloced)
Definition: channel.h:265
A structure which contains a channel implementation and session.
Definition of a media format.
Definition: format.c:43
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
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
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
Definition: muted.c:95
struct ast_party_dialed::@240 number
Dialed/Called number.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:492
struct ast_namedgroups * named_pickupgroups
Definition: res_pjsip.h:658
void ast_channel_rings_set(struct ast_channel *chan, int value)
static int compatible_formats_exist(struct ast_stream_topology *top, struct ast_format_cap *cap)
Determine if a topology is compatible with format capabilities.
Definition: chan_pjsip.c:524
#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:851
A set of tones for a given locale.
Definition: indications.h:74
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
const ast_string_field language
Definition: res_pjsip.h:822
struct ast_sip_channel_pvt * ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session)
Allocate a new SIP channel pvt structure.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
const ast_string_field accountcode
Definition: res_pjsip.h:830
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2309
struct ast_namedgroups * named_callgroups
Definition: res_pjsip.h:656
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
const ast_string_field zone
Definition: res_pjsip.h:820
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define LOG_ERROR
Definition: logger.h:285
struct ast_stream_topology * ast_channel_set_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Set the topology of streams on a channel.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:433
The PJSIP channel driver pvt, stored in the ast_sip_channel_pvt data structure.
Definition: chan_pjsip.h:42
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
#define ast_strlen_zero(a)
Definition: muted.c:73
#define ast_channel_unlock(chan)
Definition: channel.h:2838
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2523
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:756
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
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:662
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
struct ast_endpoint * persistent
Definition: res_pjsip.h:860
struct ast_stream_topology * topology
Definition: res_pjsip.h:767
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_stream_topology * topology
The media stream topology.
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:746
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
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
struct ast_variable * channel_vars
Definition: res_pjsip.h:870
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
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:738
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
struct ast_party_id id
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ chan_pjsip_pvt_dtor()

static void chan_pjsip_pvt_dtor ( void *  obj)
static

◆ chan_pjsip_queryoption()

static int chan_pjsip_queryoption ( struct ast_channel ast,
int  option,
void *  data,
int *  datalen 
)
static

Function called to query options on a channel.

Definition at line 1253 of file chan_pjsip.c.

References ast_channel_tech_pvt(), AST_OPTION_T38_STATE, ast_sip_t38_configuration::enabled, ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_channel_pvt::session, state, ast_sip_endpoint_media_configuration::t38, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_REJECTED, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_REJECTED, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_sip_session::t38state.

Referenced by chan_pjsip_pvt_dtor().

1254 {
1256  int res = -1;
1258 
1259  if (!channel) {
1260  return -1;
1261  }
1262 
1263  switch (option) {
1264  case AST_OPTION_T38_STATE:
1265  if (channel->session->endpoint->media.t38.enabled) {
1266  switch (channel->session->t38state) {
1267  case T38_LOCAL_REINVITE:
1268  case T38_PEER_REINVITE:
1269  state = T38_STATE_NEGOTIATING;
1270  break;
1271  case T38_ENABLED:
1272  state = T38_STATE_NEGOTIATED;
1273  break;
1274  case T38_REJECTED:
1275  state = T38_STATE_REJECTED;
1276  break;
1277  default:
1278  state = T38_STATE_UNKNOWN;
1279  break;
1280  }
1281  }
1282 
1283  *((enum ast_t38_state *) data) = state;
1284  res = 0;
1285 
1286  break;
1287  default:
1288  break;
1289  }
1290 
1291  return res;
1292 }
enum sip_cc_notify_state state
Definition: chan_sip.c:956
enum ast_sip_session_t38state t38state
#define T38_ENABLED
Definition: chan_ooh323.c:102
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:866
Definition: muted.c:95
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
struct ast_sip_t38_configuration t38
Definition: res_pjsip.h:763
#define AST_OPTION_T38_STATE

◆ chan_pjsip_read_stream()

static struct ast_frame * chan_pjsip_read_stream ( struct ast_channel ast)
static

Function called by core to read any waiting frames.

Note
The channel is already locked.

Definition at line 854 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ao2_ref, ast_channel_fdno(), ast_channel_get_up_time(), ast_channel_is_bridged(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_rawwriteformat(), ast_channel_readformat(), ast_channel_set_unbridged_nolock(), ast_channel_tech_pvt(), ast_channel_writeformat(), ast_debug, ast_dsp_free(), ast_dsp_get_features(), ast_dsp_process(), ast_dsp_set_features(), AST_EXTENDED_FDS, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_iscompatible_format(), ast_format_cap_remove_by_type(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, AST_LIST_NEXT, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, ast_null_frame, ast_set_read_format_path(), ast_set_write_format_path(), AST_VECTOR_GET_ADDR, AST_VECTOR_SIZE, ast_sip_endpoint::asymmetric_rtp_codec, chan_pjsip_cng_tone_detected(), ast_sip_session_media_state::default_session, ast_sip_session::dsp, DSP_FEATURE_FAX_DETECT, ast_sip_session::endpoint, ast_sip_endpoint::faxdetect_timeout, ast_frame_subclass::format, ast_frame::frametype, ast_frame_subclass::integer, is_compatible_format(), NULL, ast_sip_session_media_read_callback_state::read_callback, ast_sip_session_media_read_callback_state::session, ast_sip_channel_pvt::session, ast_frame::subclass, and ast_sip_session_media::type.

Referenced by chan_pjsip_pvt_dtor().

855 {
857  struct ast_sip_session *session = channel->session;
858  struct ast_sip_session_media_read_callback_state *callback_state;
859  struct ast_frame *f;
860  int fdno = ast_channel_fdno(ast) - AST_EXTENDED_FDS;
861  struct ast_frame *cur;
862 
863  if (fdno >= AST_VECTOR_SIZE(&session->active_media_state->read_callbacks)) {
864  return &ast_null_frame;
865  }
866 
867  callback_state = AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, fdno);
868  f = callback_state->read_callback(session, callback_state->session);
869 
870  if (!f) {
871  return f;
872  }
873 
874  for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
875  if (cur->frametype == AST_FRAME_VOICE) {
876  break;
877  }
878  }
879 
880  if (!cur || callback_state->session != session->active_media_state->default_session[callback_state->session->type]) {
881  return f;
882  }
883 
884  session = channel->session;
885 
886  /*
887  * Asymmetric RTP only has one native format set at a time.
888  * Therefore we need to update the native format to the current
889  * raw read format BEFORE the native format check
890  */
891  if (!session->endpoint->asymmetric_rtp_codec &&
893  is_compatible_format(session, cur)) {
894  struct ast_format_cap *caps;
895 
896  /* For maximum compatibility we ensure that the formats match that of the received media */
897  ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n",
900 
902  if (caps) {
905  ast_format_cap_append(caps, cur->subclass.format, 0);
907  ao2_ref(caps, -1);
908  }
909 
912 
913  if (ast_channel_is_bridged(ast)) {
915  }
916  }
917 
920  ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n",
922  ast_frfree(f);
923  return &ast_null_frame;
924  }
925 
926  if (session->dsp) {
927  int dsp_features;
928 
929  dsp_features = ast_dsp_get_features(session->dsp);
930  if ((dsp_features & DSP_FEATURE_FAX_DETECT)
931  && session->endpoint->faxdetect_timeout
932  && session->endpoint->faxdetect_timeout <= ast_channel_get_up_time(ast)) {
933  dsp_features &= ~DSP_FEATURE_FAX_DETECT;
934  if (dsp_features) {
935  ast_dsp_set_features(session->dsp, dsp_features);
936  } else {
937  ast_dsp_free(session->dsp);
938  session->dsp = NULL;
939  }
940  ast_debug(3, "Channel driver fax CNG detection timeout on %s\n",
941  ast_channel_name(ast));
942  }
943  }
944  if (session->dsp) {
945  f = ast_dsp_process(ast, session->dsp, f);
946  if (f && (f->frametype == AST_FRAME_DTMF)) {
947  if (f->subclass.integer == 'f') {
948  ast_debug(3, "Channel driver fax CNG detected on %s\n",
949  ast_channel_name(ast));
950  f = chan_pjsip_cng_tone_detected(ast, session, f);
951  /* When chan_pjsip_cng_tone_detected returns it is possible for the
952  * channel pointed to by ast and by session->channel to differ due to a
953  * masquerade. It's best not to touch things after this.
954  */
955  } else {
956  ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
957  ast_channel_name(ast));
958  }
959  }
960  }
961 
962  return f;
963 }
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1484
struct ast_sip_endpoint * endpoint
static int is_compatible_format(struct ast_sip_session *session, struct ast_frame *f)
Determine if the given frame is in a format we&#39;ve negotiated.
Definition: chan_pjsip.c:840
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1744
unsigned int asymmetric_rtp_codec
Definition: res_pjsip.h:886
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
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.
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2820
Definition: muted.c:95
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
A structure describing a SIP session.
struct ast_frame_subclass subclass
static struct ast_frame * chan_pjsip_cng_tone_detected(struct ast_channel *ast, struct ast_sip_session *session, struct ast_frame *f)
Internal helper function called when CNG tone is detected.
Definition: chan_pjsip.c:781
int ast_set_read_format_path(struct ast_channel *chan, struct ast_format *raw_format, struct ast_format *core_format)
Set specific read path on channel.
Definition: channel.c:5454
struct ast_sip_session_media_state * active_media_state
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
struct ast_dsp * dsp
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1738
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:666
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
ast_sip_session_media_read_cb read_callback
The callback to invoke.
struct ast_sip_session_media * session
The media session.
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
Structure which contains read callback information.
#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
int ast_channel_fdno(const struct ast_channel *chan)
#define AST_EXTENDED_FDS
Definition: channel.h:196
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
unsigned int faxdetect_timeout
Definition: res_pjsip.h:880
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10579
int ast_set_write_format_path(struct ast_channel *chan, struct ast_format *core_format, struct ast_format *raw_format)
Set specific write path on channel.
Definition: channel.c:5490
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1729
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_frame ast_null_frame
Definition: main/frame.c:79
enum ast_media_type type
Media type of this session media.
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
Data structure associated with a single frame of data.
enum ast_frame_type frametype
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
struct ast_format * format
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ chan_pjsip_remove_hold()

static void chan_pjsip_remove_hold ( const char *  chan_uid)
static

Remove a channel ID from the list of PJSIP channels on hold.

Parameters
chan_uid- Unique ID of the channel being taken out of the hold list

Definition at line 1164 of file chan_pjsip.c.

References ao2_find, OBJ_NODATA, OBJ_SEARCH_KEY, and OBJ_UNLINK.

Referenced by chan_pjsip_indicate(), and chan_pjsip_session_end().

1165 {
1167 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1123
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ chan_pjsip_request()

static struct ast_channel * chan_pjsip_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
)
static

Definition at line 2761 of file chan_pjsip.c.

References ast_stream_topology_create_from_format_cap(), ast_stream_topology_free(), rtp_direct_media_data::chan, chan_pjsip_request_with_stream_topology(), and NULL.

Referenced by chan_pjsip_pvt_dtor().

2762 {
2763  struct ast_stream_topology *topology;
2764  struct ast_channel *chan;
2765 
2767  if (!topology) {
2768  return NULL;
2769  }
2770 
2771  chan = chan_pjsip_request_with_stream_topology(type, topology, assignedids, requestor, data, cause);
2772 
2773  ast_stream_topology_free(topology);
2774 
2775  return chan;
2776 }
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
struct ast_stream_topology * ast_stream_topology_create_from_format_cap(struct ast_format_cap *cap)
A helper function that, given a format capabilities structure, creates a topology and separates the m...
Definition: stream.c:835
#define NULL
Definition: resample.c:96
const char * data
static struct ast_channel * chan_pjsip_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Function called by core to create a new outgoing PJSIP session.
Definition: chan_pjsip.c:2734
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:738

◆ chan_pjsip_request_with_stream_topology()

static struct ast_channel * chan_pjsip_request_with_stream_topology ( const char *  type,
struct ast_stream_topology topology,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
)
static

Function called by core to create a new outgoing PJSIP session.

Definition at line 2734 of file chan_pjsip.c.

References ao2_cleanup, AST_CAUSE_FAILURE, ast_channel_name(), ast_sip_push_task_wait_servant(), AST_STATE_DOWN, ast_str_tmp, ast_stream_topology_to_str(), request_data::cause, chan_pjsip_new(), ast_sip_session::channel, request_data::dest, NULL, RAII_VAR, request(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, request_data::session, and request_data::topology.

Referenced by chan_pjsip_pvt_dtor(), and chan_pjsip_request().

2735 {
2736  struct request_data req_data;
2738  SCOPE_ENTER(1, "%s Topology: %s\n", data,
2739  ast_str_tmp(256, ast_stream_topology_to_str(topology, &STR_TMP)));
2740 
2741  req_data.topology = topology;
2742  req_data.dest = data;
2743  /* Default failure value in case ast_sip_push_task_wait_servant() itself fails. */
2744  req_data.cause = AST_CAUSE_FAILURE;
2745 
2746  if (ast_sip_push_task_wait_servant(NULL, request, &req_data)) {
2747  *cause = req_data.cause;
2748  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't push task\n");
2749  }
2750 
2751  session = req_data.session;
2752 
2753  if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
2754  /* Session needs to be terminated prematurely */
2755  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
2756  }
2757 
2758  SCOPE_EXIT_RTN_VALUE(session->channel, "Channel: %s\n", ast_channel_name(session->channel));
2759 }
static struct ast_channel * chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
Function called to create a new PJSIP Asterisk channel.
Definition: chan_pjsip.c:545
#define NULL
Definition: resample.c:96
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:5051
A structure describing a SIP session.
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:921
#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:851
static struct ast_mansession session
#define AST_CAUSE_FAILURE
Definition: causes.h:149
struct ast_stream_topology * topology
Definition: chan_pjsip.c:2621
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
static int request(void *obj)
Definition: chan_pjsip.c:2626
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)

◆ chan_pjsip_sendtext()

static int chan_pjsip_sendtext ( struct ast_channel ast,
const char *  text 
)
static

Definition at line 2919 of file chan_pjsip.c.

References ARRAY_LEN, ast_free, ast_msg_data_alloc(), AST_MSG_DATA_ATTR_BODY, AST_MSG_DATA_SOURCE_TYPE_UNKNOWN, chan_pjsip_sendtext_data(), and ast_msg_data_attribute::type.

Referenced by chan_pjsip_pvt_dtor().

2920 {
2921  struct ast_msg_data *msg;
2922  int rc;
2923  struct ast_msg_data_attribute attrs[] =
2924  {
2925  {
2927  .value = (char *)text,
2928  }
2929  };
2930 
2932  if (!msg) {
2933  return -1;
2934  }
2935  rc = chan_pjsip_sendtext_data(ast, msg);
2936  ast_free(msg);
2937 
2938  return rc;
2939 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
enum ast_msg_data_attribute_type type
Definition: message.h:463
Structure used to transport a message through the frame core.
Definition: message.c:1369
struct ast_msg_data * ast_msg_data_alloc(enum ast_msg_data_source_type source, struct ast_msg_data_attribute attributes[], size_t count)
Allocates an ast_msg_data structure.
Definition: message.c:1381
char * text
Definition: app_queue.c:1511
static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg)
Function called by core to send text on PJSIP session.
Definition: chan_pjsip.c:2886
#define ast_free(a)
Definition: astmm.h:182

◆ chan_pjsip_sendtext_data()

static int chan_pjsip_sendtext_data ( struct ast_channel ast,
struct ast_msg_data msg 
)
static

Function called by core to send text on PJSIP session.

Definition at line 2886 of file chan_pjsip.c.

References ao2_ref, ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_log, AST_MSG_DATA_ATTR_BODY, AST_MSG_DATA_ATTR_FROM, AST_MSG_DATA_ATTR_TO, ast_msg_data_get_attribute(), ast_sip_push_task(), ast_sip_session::inv_session, LOG_ERROR, sendtext(), sendtext_data_create(), ast_sip_session::serializer, ast_sip_channel_pvt::session, and sendtext_data::session.

Referenced by chan_pjsip_pvt_dtor(), and chan_pjsip_sendtext().

2887 {
2889  struct sendtext_data *data = sendtext_data_create(ast, msg);
2890 
2891  ast_debug(1, "Sending MESSAGE from '%s' to '%s:%s': %s\n",
2894  ast_channel_name(ast),
2896 
2897  if (!data) {
2898  return -1;
2899  }
2900 
2901 #ifdef HAVE_PJSIP_INV_SESSION_REF
2902  if (pjsip_inv_add_ref(data->session->inv_session) != PJ_SUCCESS) {
2903  ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
2904  ao2_ref(data, -1);
2905  return -1;
2906  }
2907 #endif
2908 
2909  if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
2910 #ifdef HAVE_PJSIP_INV_SESSION_REF
2911  pjsip_inv_dec_ref(data->session->inv_session);
2912 #endif
2913  ao2_ref(data, -1);
2914  return -1;
2915  }
2916  return 0;
2917 }
static struct sendtext_data * sendtext_data_create(struct ast_channel *chan, struct ast_msg_data *msg)
Definition: chan_pjsip.c:2790
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_sip_session * session
Definition: chan_pjsip.c:2779
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
struct pjsip_inv_session * inv_session
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
Definition: message.c:1496
const char * ast_channel_name(const struct ast_channel *chan)
static int sendtext(void *obj)
Definition: chan_pjsip.c:2811

◆ chan_pjsip_session_begin()

static void chan_pjsip_session_begin ( struct ast_sip_session session)
static

SIP session interaction functions.

Definition at line 3032 of file chan_pjsip.c.

References ao2_cleanup, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_name(), ast_sip_endpoint_media_configuration::direct_media, ast_sip_session::endpoint, ast_sip_direct_media_configuration::glare_mitigation, ast_sip_endpoint::media, NULL, RAII_VAR, SCOPE_ENTER, and SCOPE_EXIT_RTN.

3033 {
3034  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
3035  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
3036 
3037  if (session->endpoint->media.direct_media.glare_mitigation ==
3039  SCOPE_EXIT_RTN("Direct media no glare mitigation\n");
3040  }
3041 
3043  "direct_media_glare_mitigation");
3044 
3045  if (!datastore) {
3046  SCOPE_EXIT_RTN("Couldn't create datastore\n");
3047  }
3048 
3049  ast_sip_session_add_datastore(session, datastore);
3050  SCOPE_EXIT_RTN();
3051 }
struct ast_sip_endpoint * endpoint
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
static struct ast_datastore_info direct_media_mitigation_info
Definition: chan_pjsip.c:264
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:761
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
#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:851
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN(...)
Definition: logger.h:876
enum ast_sip_direct_media_glare_mitigation glare_mitigation
Definition: res_pjsip.h:730
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.

◆ chan_pjsip_session_end()

static void chan_pjsip_session_end ( struct ast_sip_session session)
static

Function called when the session ends.

Definition at line 3054 of file chan_pjsip.c.

References ast_channel_hangupcause(), ast_channel_name(), ast_channel_uniqueid(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_set_hangupsource(), ast_sip_session_get_name(), chan_pjsip_remove_hold(), ast_sip_session::channel, hangup_sip2cause(), ast_sip_session::inv_session, SCOPE_ENTER, and SCOPE_EXIT_RTN.

3055 {
3056  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
3057 
3058  if (!session->channel) {
3059  SCOPE_EXIT_RTN("No channel\n");
3060  }
3061 
3063 
3064  ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
3065  if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
3066  int cause = hangup_sip2cause(session->inv_session->cause);
3067 
3068  ast_queue_hangup_with_cause(session->channel, cause);
3069  } else {
3070  ast_queue_hangup(session->channel);
3071  }
3072 
3073  SCOPE_EXIT_RTN();
3074 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1146
struct pjsip_inv_session * inv_session
static void chan_pjsip_remove_hold(const char *chan_uid)
Remove a channel ID from the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1164
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1162
static int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_pjsip.c:2942
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2479
struct ast_channel * channel
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN(...)
Definition: logger.h:876
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)

◆ chan_pjsip_set_rtp_peer()

static int chan_pjsip_set_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance rtp,
struct ast_rtp_instance vrtp,
struct ast_rtp_instance tpeer,
const struct ast_format_cap cap,
int  nat_active 
)
static

Function called by RTP engine to change where the remote party should send media.

Definition at line 446 of file chan_pjsip.c.

References ao2_ref, ast_channel_is_bridged(), ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_log, ast_sip_push_task(), ast_str_tmp, cdata(), ast_sip_endpoint_media_configuration::direct_media, ast_sip_direct_media_configuration::disable_on_nat, ast_sip_session::endpoint, LOG_ERROR, ast_sip_endpoint::media, rtp_direct_media_data_create(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, send_direct_media_request(), ast_sip_session::serializer, and ast_sip_channel_pvt::session.

452 {
454  struct ast_sip_session *session = channel->session;
456  SCOPE_ENTER(1, "%s %s\n", ast_channel_name(chan),
458 
459  /* Don't try to do any direct media shenanigans on early bridges */
460  if ((rtp || vrtp || tpeer) && !ast_channel_is_bridged(chan)) {
461  ast_debug(4, "Disregarding setting RTP on %s: channel is not bridged\n", ast_channel_name(chan));
462  SCOPE_EXIT_RTN_VALUE(0, "Channel not bridged\n");
463  }
464 
465  if (nat_active && session->endpoint->media.direct_media.disable_on_nat) {
466  ast_debug(4, "Disregarding setting RTP on %s: NAT is active\n", ast_channel_name(chan));
467  SCOPE_EXIT_RTN_VALUE(0, "NAT is active\n");
468  }
469 
470  cdata = rtp_direct_media_data_create(chan, rtp, vrtp, cap, session);
471  if (!cdata) {
473  }
474 
476  ast_log(LOG_ERROR, "Unable to send direct media request for channel %s\n", ast_channel_name(chan));
477  ao2_ref(cdata, -1);
478  }
479 
481 }
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:761
A structure describing a SIP session.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int send_direct_media_request(void *data)
Definition: chan_pjsip.c:394
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10579
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
static int cdata(void *userdata, int state, const char *cdata, size_t len)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
static struct rtp_direct_media_data * rtp_direct_media_data_create(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, const struct ast_format_cap *cap, struct ast_sip_session *session)
Definition: chan_pjsip.c:375
const char * ast_channel_name(const struct ast_channel *chan)

◆ chan_pjsip_transfer()

static int chan_pjsip_transfer ( struct ast_channel ast,
const char *  target 
)
static

Function called by core for Asterisk initiated transfer.

Definition at line 2165 of file chan_pjsip.c.

References ao2_cleanup, ast_channel_tech_pvt(), ast_log, ast_sip_push_task(), ast_sip_session::inv_session, LOG_ERROR, LOG_WARNING, ast_sip_session::serializer, ast_sip_channel_pvt::session, transfer_data::session, transfer(), and transfer_data_alloc().

Referenced by chan_pjsip_pvt_dtor().

2166 {
2168  struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
2169 
2170  if (!trnf_data) {
2171  return -1;
2172  }
2173 
2174 #ifdef HAVE_PJSIP_INV_SESSION_REF
2175  if (pjsip_inv_add_ref(trnf_data->session->inv_session) != PJ_SUCCESS) {
2176  ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
2177  ao2_cleanup(trnf_data);
2178  return -1;
2179  }
2180 #endif
2181 
2182  if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
2183  ast_log(LOG_WARNING, "Error requesting transfer\n");
2184 #ifdef HAVE_PJSIP_INV_SESSION_REF
2185  pjsip_inv_dec_ref(trnf_data->session->inv_session);
2186 #endif
2187  ao2_cleanup(trnf_data);
2188  return -1;
2189  }
2190 
2191  return 0;
2192 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1893
static int transfer(void *data)
Definition: chan_pjsip.c:2126
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
static struct transfer_data * transfer_data_alloc(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1905
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
struct pjsip_inv_session * inv_session
#define ast_log
Definition: astobj2.c:42
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ chan_pjsip_write()

static int chan_pjsip_write ( struct ast_channel ast,
struct ast_frame f 
)
static

Definition at line 1055 of file chan_pjsip.c.

References chan_pjsip_write_stream().

Referenced by chan_pjsip_pvt_dtor().

1056 {
1057  return chan_pjsip_write_stream(ast, -1, frame);
1058 }
static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f)
Definition: chan_pjsip.c:965

◆ chan_pjsip_write_stream()

static int chan_pjsip_write_stream ( struct ast_channel ast,
int  stream_num,
struct ast_frame f 
)
static

Definition at line 965 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ast_channel_name(), ast_channel_nativeformats(), ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_channel_readformat(), ast_channel_readtrans(), ast_channel_tech_pvt(), ast_channel_writeformat(), ast_channel_writetrans(), ast_codec_media_type2str(), ast_debug, ast_format_cap_get_names(), ast_format_cap_iscompatible_format(), AST_FORMAT_CAP_NAMES_LEN, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_CNG, AST_FRAME_MODEM, AST_FRAME_RTCP, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_IMAGE, AST_MEDIA_TYPE_VIDEO, AST_RTP_RTCP_PSFB, ast_str_alloca, ast_translate_path_to_str(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sip_session_media_state::default_session, ast_frame_subclass::format, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, NULL, ast_sip_channel_pvt::session, ast_frame::subclass, ast_sip_session_media::type, and ast_sip_session_media::write_callback.

Referenced by chan_pjsip_pvt_dtor(), and chan_pjsip_write().

966 {
968  struct ast_sip_session *session = channel->session;
969  struct ast_sip_session_media *media = NULL;
970  int res = 0;
971 
972  /* The core provides a guarantee that the stream will exist when we are called if stream_num is provided */
973  if (stream_num >= 0) {
974  /* What is not guaranteed is that a media session will exist */
975  if (stream_num < AST_VECTOR_SIZE(&channel->session->active_media_state->sessions)) {
976  media = AST_VECTOR_GET(&channel->session->active_media_state->sessions, stream_num);
977  }
978  }
979 
980  switch (frame->frametype) {
981  case AST_FRAME_VOICE:
982  if (!media) {
983  return 0;
984  } else if (media->type != AST_MEDIA_TYPE_AUDIO) {
985  ast_debug(3, "Channel %s stream %d is of type '%s', not audio!\n",
987  return 0;
988  } else if (media == channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO] &&
991  struct ast_str *write_transpath = ast_str_alloca(256);
992  struct ast_str *read_transpath = ast_str_alloca(256);
993 
995  "Channel %s asked to send %s frame when native formats are %s (rd:%s->%s;%s wr:%s->%s;%s)\n",
996  ast_channel_name(ast),
997  ast_format_get_name(frame->subclass.format),
1001  ast_translate_path_to_str(ast_channel_readtrans(ast), &read_transpath),
1004  ast_translate_path_to_str(ast_channel_writetrans(ast), &write_transpath));
1005  return 0;
1006  } else if (media->write_callback) {
1007  res = media->write_callback(session, media, frame);
1008 
1009  }
1010  break;
1011  case AST_FRAME_VIDEO:
1012  if (!media) {
1013  return 0;
1014  } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
1015  ast_debug(3, "Channel %s stream %d is of type '%s', not video!\n",
1016  ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1017  return 0;
1018  } else if (media->write_callback) {
1019  res = media->write_callback(session, media, frame);
1020  }
1021  break;
1022  case AST_FRAME_MODEM:
1023  if (!media) {
1024  return 0;
1025  } else if (media->type != AST_MEDIA_TYPE_IMAGE) {
1026  ast_debug(3, "Channel %s stream %d is of type '%s', not image!\n",
1027  ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1028  return 0;
1029  } else if (media->write_callback) {
1030  res = media->write_callback(session, media, frame);
1031  }
1032  break;
1033  case AST_FRAME_CNG:
1034  break;
1035  case AST_FRAME_RTCP:
1036  /* We only support writing out feedback */
1037  if (frame->subclass.integer != AST_RTP_RTCP_PSFB || !media) {
1038  return 0;
1039  } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
1040  ast_debug(3, "Channel %s stream %d is of type '%s', not video! Unable to write RTCP feedback.\n",
1041  ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1042  return 0;
1043  } else if (media->write_callback) {
1044  res = media->write_callback(session, media, frame);
1045  }
1046  break;
1047  default:
1048  ast_log(LOG_WARNING, "Can't send %u type frames with PJSIP\n", frame->frametype);
1049  break;
1050  }
1051 
1052  return res;
1053 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:347
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
ast_sip_session_media_write_cb write_callback
The write callback when writing frames.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
A structure describing a SIP session.
struct ast_trans_pvt * ast_channel_readtrans(const struct ast_channel *chan)
struct ast_sip_session_media_state * active_media_state
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
struct ast_trans_pvt * ast_channel_writetrans(const struct ast_channel *chan)
static struct ast_mansession session
int stream_num
The stream number to place into any resulting frames.
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
A structure containing SIP session media information.
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:678
enum ast_media_type type
Media type of this session media.
const char * ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str)
Puts a string representation of the translation path into outbuf.
Definition: translate.c:922
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_RTP_RTCP_PSFB
Definition: rtp_engine.h:298
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ check_for_rtp_changes()

static int check_for_rtp_changes ( struct ast_channel chan,
struct ast_rtp_instance rtp,
struct ast_sip_session_media media,
struct ast_sip_session session 
)
static
Precondition
chan is locked

Definition at line 317 of file chan_pjsip.c.

References ast_channel_set_fd(), AST_EXTENDED_FDS, ast_rtp_instance_fd(), ast_rtp_instance_get_and_cmp_remote_address, ast_rtp_instance_set_last_rx(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sip_session_media::direct_media_addr, NULL, ast_sip_session_media::rtp, and rtp_find_rtcp_fd_position().

Referenced by send_direct_media_request().

319 {
320  int changed = 0, position = -1;
321 
322  if (media->rtp) {
323  position = rtp_find_rtcp_fd_position(session, media->rtp);
324  }
325 
326  if (rtp) {
328  if (media->rtp) {
329  if (position != -1) {
330  ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, -1);
331  }
333  }
334  } else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
336  changed = 1;
337  if (media->rtp) {
338  /* Direct media has ended - reset time of last received RTP packet
339  * to avoid premature RTP timeout. Synchronisation between the
340  * modification of direct_mdedia_addr+last_rx here and reading the
341  * values in res_pjsip_sdp_rtp.c:rtp_check_timeout() is provided
342  * by the channel's lock (which is held while this function is
343  * executed).
344  */
345  ast_rtp_instance_set_last_rx(media->rtp, time(NULL));
347  if (position != -1) {
348  ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, ast_rtp_instance_fd(media->rtp, 1));
349  }
350  }
351  }
352 
353  return changed;
354 }
struct ast_sockaddr direct_media_addr
Direct media address.
#define NULL
Definition: resample.c:96
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define AST_EXTENDED_FDS
Definition: channel.h:196
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2406
struct ast_rtp_instance * rtp
RTP instance itself.
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
static int rtp_find_rtcp_fd_position(struct ast_sip_session *session, struct ast_rtp_instance *rtp)
Helper function to find the position for RTCP.
Definition: chan_pjsip.c:296
#define ast_rtp_instance_get_and_cmp_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to, comparing its address to another...
Definition: rtp_engine.h:1227
void ast_rtp_instance_set_last_rx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP reception time.
Definition: rtp_engine.c:3705

◆ clear_session_and_channel()

static void clear_session_and_channel ( struct ast_sip_session session,
struct ast_channel ast 
)
static

Clear a channel from a session along with its PVT.

Definition at line 2543 of file chan_pjsip.c.

References ast_channel_tech_pvt_set(), ast_sip_session::channel, NULL, and set_channel_on_rtp_instance().

Referenced by chan_pjsip_hangup(), and hangup().

2544 {
2545  session->channel = NULL;
2546  set_channel_on_rtp_instance(session, "");
2548 }
#define NULL
Definition: resample.c:96
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:492
struct ast_channel * channel
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

◆ compatible_formats_exist()

static int compatible_formats_exist ( struct ast_stream_topology top,
struct ast_format_cap cap 
)
static

Determine if a topology is compatible with format capabilities.

This will return true if ANY formats in the topology are compatible with the format capabilities.

XXX When supporting true multistream, we will need to be sure to mark which streams from top1 are compatible with which streams from top2. Then the ones that are not compatible will need to be marked as "removed" so that they are negotiated as expected.

Parameters
topTopology
capFormat capabilities
Return values
1The topology has at least one compatible format
0The topology has no compatible formats or an error occurred.

Definition at line 524 of file chan_pjsip.c.

References ao2_ref, ast_format_cap_get_names(), ast_format_cap_iscompatible(), AST_FORMAT_CAP_NAMES_LEN, ast_str_tmp, ast_stream_topology_get_formats(), ast_stream_topology_to_str(), SCOPE_ENTER, and SCOPE_EXIT_RTN_VALUE.

Referenced by chan_pjsip_new().

525 {
526  struct ast_format_cap *cap_from_top;
527  int res;
528  SCOPE_ENTER(1, "Topology: %s Formats: %s\n",
531 
532  cap_from_top = ast_stream_topology_get_formats(top);
533 
534  if (!cap_from_top) {
535  SCOPE_EXIT_RTN_VALUE(0, "Topology had no formats\n");
536  }
537 
538  res = ast_format_cap_iscompatible(cap_from_top, cap);
539  ao2_ref(cap_from_top, -1);
540 
541  SCOPE_EXIT_RTN_VALUE(res, "Compatible? %s\n", res ? "yes" : "no");
542 }
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
Definition: stream.c:915
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:921
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition: format_cap.c:655

◆ direct_media_mitigate_glare()

static int direct_media_mitigate_glare ( struct ast_sip_session session)
static

Definition at line 266 of file chan_pjsip.c.

References ao2_cleanup, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING, ast_sip_session_get_datastore(), ast_sip_session_remove_datastore(), ast_sip_endpoint_media_configuration::direct_media, ast_sip_session::endpoint, ast_sip_direct_media_configuration::glare_mitigation, ast_sip_session::inv_session, ast_sip_endpoint::media, NULL, and RAII_VAR.

Referenced by send_direct_media_request().

267 {
268  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
269 
272  return 0;
273  }
274 
275  datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
276  if (!datastore) {
277  return 0;
278  }
279 
280  /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
281  ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
282 
283  if ((session->endpoint->media.direct_media.glare_mitigation ==
285  session->inv_session->role == PJSIP_ROLE_UAC) ||
288  session->inv_session->role == PJSIP_ROLE_UAS)) {
289  return 1;
290  }
291 
292  return 0;
293 }
struct ast_sip_endpoint * endpoint
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:761
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:836
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_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:851
enum ast_sip_direct_media_glare_mitigation glare_mitigation
Definition: res_pjsip.h:730
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ handle_topology_request_change()

static int handle_topology_request_change ( struct ast_sip_session session,
const struct ast_stream_topology proposed 
)
static

Definition at line 1620 of file chan_pjsip.c.

References ast_sip_push_task(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, send_topology_change_refresh(), ast_sip_session::serializer, topology_change_refresh_data_alloc(), and topology_change_refresh_data_free().

Referenced by chan_pjsip_indicate().

1622 {
1624  int res;
1625  SCOPE_ENTER(1);
1626 
1627  refresh_data = topology_change_refresh_data_alloc(session, proposed);
1628  if (!refresh_data) {
1629  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create refresh_data\n");
1630  }
1631 
1632  res = ast_sip_push_task(session->serializer, send_topology_change_refresh, refresh_data);
1633  if (res) {
1634  topology_change_refresh_data_free(refresh_data);
1635  }
1636  SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
1637 }
static struct topology_change_refresh_data * topology_change_refresh_data_alloc(struct ast_sip_session *session, const struct ast_stream_topology *topology)
Definition: chan_pjsip.c:1561
static int send_topology_change_refresh(void *data)
Definition: chan_pjsip.c:1606
struct ast_taskprocessor * serializer
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:4985
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
Definition: chan_pjsip.c:1553

◆ hangup()

static int hangup ( void *  data)
static

Definition at line 2550 of file chan_pjsip.c.

References ao2_bump, ao2_cleanup, ast_channel_name(), ast_channel_tech_pvt(), ast_sip_session_terminate(), hangup_data::cause, hangup_data::chan, clear_session_and_channel(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and ast_sip_channel_pvt::session.

Referenced by ast_hangup(), chan_pjsip_hangup(), hangup_playback(), and manage_calls().

2551 {
2552  struct hangup_data *h_data = data;
2553  struct ast_channel *ast = h_data->chan;
2555  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2556 
2557  /*
2558  * Before cleaning we have to ensure that channel or its session is not NULL
2559  * we have seen rare case when taskprocessor calls hangup but channel is NULL
2560  * due to SIP session timeout and answer happening at the same time
2561  */
2562  if (channel) {
2563  struct ast_sip_session *session = channel->session;
2564  if (session) {
2565  int cause = h_data->cause;
2566 
2567  /*
2568  * It's possible that session_terminate might cause the session to be destroyed
2569  * immediately so we need to keep a reference to it so we can NULL session->channel
2570  * afterwards.
2571  */
2572  ast_sip_session_terminate(ao2_bump(session), cause);
2573  clear_session_and_channel(session, ast);
2574  ao2_cleanup(session);
2575  }
2576  ao2_cleanup(channel);
2577  }
2578  ao2_cleanup(h_data);
2580 }
Main Channel structure associated with a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
A structure describing a SIP session.
#define ao2_bump(obj)
Definition: astobj2.h:491
static struct ast_mansession session
struct ast_channel * chan
Definition: chan_pjsip.c:2518
#define SCOPE_ENTER(level,...)
Definition: logger.h:872
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:877
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast)
Clear a channel from a session along with its PVT.
Definition: chan_pjsip.c:2543

◆ hangup_cause2sip()

static int hangup_cause2sip ( int  cause)
static

Internal function which translates from Asterisk cause codes to SIP response codes.

Definition at line 2469 of file chan_pjsip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.

Referenced by chan_pjsip_hangup().

2470 {
2471  switch (cause) {
2472  case AST_CAUSE_UNALLOCATED: /* 1 */
2473  case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
2474  case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
2475  return 404;
2476  case AST_CAUSE_CONGESTION: /* 34 */
2477  case AST_CAUSE_SWITCH_CONGESTION: /* 42 */
2478  return 503;
2479  case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
2480  return 408;
2481  case AST_CAUSE_NO_ANSWER: /* 19 */
2482  case AST_CAUSE_UNREGISTERED: /* 20 */
2483  return 480;
2484  case AST_CAUSE_CALL_REJECTED: /* 21 */
2485  return 403;
2486  case AST_CAUSE_NUMBER_CHANGED: /* 22 */
2487  return 410;
2488  case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */
2489  return 480;
2491  return 484;
2492  case AST_CAUSE_USER_BUSY:
2493  return 486;
2494  case AST_CAUSE_FAILURE:
2495  return 500;
2496  case AST_CAUSE_FACILITY_REJECTED: /* 29 */
2497  return 501;
2499  return 503;
2501  return 502;
2502  case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
2503  return 488;
2504  case AST_CAUSE_INTERWORKING: /* Unspecified Interworking issues */
2505  return 500;
2506  case AST_CAUSE_NOTDEFINED:
2507  default:
2508  ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
2509  return 0;
2510  }
2511 
2512  /* Never reached */
2513  return 0;
2514 }
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
#define AST_CAUSE_FACILITY_REJECTED
Definition: causes.h:116
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:107
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
Definition: causes.h:98
#define AST_CAUSE_CHAN_NOT_IMPLEMENTED
Definition: causes.h:131
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
#define AST_CAUSE_NOTDEFINED
Definition: causes.h:154
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
#define AST_CAUSE_FAILURE
Definition: causes.h:149
#define AST_CAUSE_NORMAL_UNSPECIFIED
Definition: causes.h:118
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:153
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:111
#define AST_CAUSE_INTERWORKING
Definition: causes.h:145
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
#define AST_CAUSE_CONGESTION
Definition: causes.h:152

◆ hangup_data_alloc()

static struct hangup_data* hangup_data_alloc ( int  cause,
struct ast_channel chan 
)
static

Definition at line 2528 of file chan_pjsip.c.

References ao2_alloc, ast_channel_ref, hangup_data::cause, hangup_data::chan, hangup_data_destroy(), and NULL.

Referenced by chan_pjsip_hangup().

2529 {
2530  struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
2531 
2532  if (!h_data) {
2533  return NULL;
2534  }
2535 
2536  h_data->cause = cause;
2537  h_data->chan = ast_channel_ref(chan);
2538 
2539  return h_data;
2540 }
static void hangup_data_destroy(void *obj)
Definition: chan_pjsip.c:2521
#define NULL
Definition: resample.c:96
struct ast_channel * chan
Definition: chan_pjsip.c:2518
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2862

◆ hangup_data_destroy()

static void hangup_data_destroy ( void *  obj)
static

Definition at line 2521 of file chan_pjsip.c.

References ast_channel_unref, and hangup_data::chan.

Referenced by hangup_data_alloc().

2522 {
2523  struct hangup_data *h_data = obj;
2524 
2525  h_data->chan = ast_channel_unref(h_data->chan);
2526 }
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2873
struct ast_channel * chan
Definition: chan_pjsip.c:2518

◆ hangup_sip2cause()

static int hangup_sip2cause ( int  cause)
static

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 2942 of file chan_pjsip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by chan_pjsip_incoming_response(), and chan_pjsip_session_end().

2943 {
2944  /* Possible values taken from causes.h */
2945 
2946  switch(cause) {
2947  case 401: /* Unauthorized */
2948  return AST_CAUSE_CALL_REJECTED;
2949  case 403: /* Not found */
2950  return AST_CAUSE_CALL_REJECTED;
2951  case 404: /* Not found */
2952  return AST_CAUSE_UNALLOCATED;
2953  case 405: /* Method not allowed */
2954  return AST_CAUSE_INTERWORKING;
2955  case 407: /* Proxy authentication required */
2956  return AST_CAUSE_CALL_REJECTED;
2957  case 408: /* No reaction */
2959  case 409: /* Conflict */
2961  case 410: /* Gone */
2962  return AST_CAUSE_NUMBER_CHANGED;
2963  case 411: /* Length required */
2964  return AST_CAUSE_INTERWORKING;
2965  case 413: /* Request entity too large */
2966  return AST_CAUSE_INTERWORKING;
2967  case 414: /* Request URI too large */
2968  return AST_CAUSE_INTERWORKING;
2969  case 415: /* Unsupported media type */
2970  return AST_CAUSE_INTERWORKING;
2971  case 420: /* Bad extension */
2973  case 480: /* No answer */
2974  return AST_CAUSE_NO_ANSWER;
2975  case 481: /* No answer */
2976  return AST_CAUSE_INTERWORKING;
2977  case 482: /* Loop detected */
2978  return AST_CAUSE_INTERWORKING;
2979  case 483: /* Too many hops */
2980  return AST_CAUSE_NO_ANSWER;
2981  case 484: /* Address incomplete */
2983  case 485: /* Ambiguous */
2984  return AST_CAUSE_UNALLOCATED;
2985  case 486: /* Busy everywhere */
2986  return AST_CAUSE_BUSY;
2987  case 487: /* Request terminated */
2988  return AST_CAUSE_INTERWORKING;
2989  case 488: /* No codecs approved */
2991  case 491: /* Request pending */
2992  return AST_CAUSE_INTERWORKING;
2993  case 493: /* Undecipherable */
2994  return AST_CAUSE_INTERWORKING;
2995  case 500: /* Server internal failure */
2996  return AST_CAUSE_FAILURE;
2997  case 501: /* Call rejected */
2999  case 502:
3001  case 503: /* Service unavailable */
3002  return AST_CAUSE_CONGESTION;
3003  case 504: /* Gateway timeout */
3004  return