Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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"
Include dependency graph for chan_pjsip.c:

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 void chan_pjsip_incoming_response_update_cause (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)
 Asterisk core interaction functions. More...
 
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 void set_sipdomain_variable (struct ast_sip_session *session)
 
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.

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 3459 of file chan_pjsip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3459 of file chan_pjsip.c.

◆ answer()

static int answer ( void *  data)
static

Definition at line 675 of file chan_pjsip.c.

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

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

Referenced by add_bundle_groups(), add_sdp_streams(), ast_dns_resolver_set_result(), ast_raw_answer_with_stream_topology(), ast_search_dns(), ast_stun_request(), ast_unreal_answer(), chan_pjsip_answer(), dns_parse_answer(), dns_parse_answer_ex(), dump_answer(), ebl_callback(), enum_callback(), find_and_retrans(), parse_naptr(), parse_srv(), pbx_builtin_incomplete(), session_inv_on_rx_offer(), srv_callback(), stun_monitor_request(), tds_log(), txt_callback(), and zapateller_exec().

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3459 of file chan_pjsip.c.

◆ call()

static int call ( void *  data)
static

Definition at line 2379 of file chan_pjsip.c.

2380 {
2381  struct ast_sip_channel_pvt *channel = data;
2382  struct ast_sip_session *session = channel->session;
2383  pjsip_tx_data *tdata;
2384  int res = 0;
2385  SCOPE_ENTER(1, "%s Topology: %s\n",
2387  ast_str_tmp(256, ast_stream_topology_to_str(channel->session->pending_media_state->topology, &STR_TMP))
2388  );
2389 
2390 
2391  res = ast_sip_session_create_invite(session, &tdata);
2392 
2393  if (res) {
2394  ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2395  ast_queue_hangup(session->channel);
2396  } else {
2400  }
2401  ao2_ref(channel, -1);
2402  SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
2403 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static void update_initial_connected_line(struct ast_sip_session *session)
Definition: chan_pjsip.c:2354
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:486
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1144
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
Definition: channel.c:2498
#define SCOPE_ENTER(level,...)
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
Creates an INVITE request.
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:936
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1167
A structure which contains a channel implementation and session.
struct ast_channel * channel

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, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, set_channel_on_rtp_instance(), and update_initial_connected_line().

Referenced by ast_call(), can_ring_entry(), chan_pjsip_call(), close_rtp_connection(), close_udptl_connection(), configure_local_rtp(), find_call(), native_start(), onAlerting(), onCallCleared(), onCallEstablished(), onModeChanged(), onNewCallCreated(), onOutgoingCall(), onProgress(), ooh323_onReceivedDigit(), ooh323_onReceivedSetup(), ooh323_set_read_format(), ooh323_set_write_format(), ooh323c_set_capability_for_call(), ooh323c_start_call_thread(), ooh323c_start_receive_channel(), ooh323c_start_transmit_channel(), ooh323c_start_transmit_datachannel(), ooh323c_stop_call_thread(), ooh323c_stop_transmit_channel(), ooh323c_stop_transmit_datachannel(), setup_rtp_connection(), setup_rtp_remote(), setup_udptl_connection(), and update_our_aliases().

◆ call_pickup_incoming_request()

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

Definition at line 3086 of file chan_pjsip.c.

3087 {
3088  struct ast_features_pickup_config *pickup_cfg;
3089  struct ast_channel *chan;
3090 
3091  /* Check for a to-tag to determine if this is a reinvite */
3092  if (rdata->msg_info.to->tag.slen) {
3093  /* We don't care about reinvites */
3094  return 0;
3095  }
3096 
3097  pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
3098  if (!pickup_cfg) {
3099  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
3100  return 0;
3101  }
3102 
3103  if (strcmp(session->exten, pickup_cfg->pickupexten)) {
3104  ao2_ref(pickup_cfg, -1);
3105  return 0;
3106  }
3107  ao2_ref(pickup_cfg, -1);
3108 
3109  /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
3110  * changing the channel pointer in session to a different channel. To ensure we work on the right channel
3111  * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
3112  */
3113  chan = ast_channel_ref(session->channel);
3114  if (ast_pickup_call(chan)) {
3116  } else {
3118  }
3119  /* A hangup always occurs because the pickup operation will have either failed resulting in the call
3120  * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
3121  * the channel that was replaced, which should be hung up since it is literally in limbo not connected
3122  * to anything at all.
3123  */
3124  ast_hangup(chan);
3125  ast_channel_unref(chan);
3126 
3127  return 1;
3128 }
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:111
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2542
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:199
Main Channel structure associated with a channel.
Configuration relating to call pickup.

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(), LOG_ERROR, ast_features_pickup_config::pickupexten, and session.

◆ 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 1110 of file chan_pjsip.c.

1111 {
1112  RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1113 
1114  hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1115  if (hold_uid) {
1116  /* Device is already on hold. Nothing to do. */
1117  return 0;
1118  }
1119 
1120  /* Device wasn't in hold list already. Create a new one. */
1121  hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
1123  if (!hold_uid) {
1124  return -1;
1125  }
1126 
1127  ast_copy_string(hold_uid, chan_uid, strlen(chan_uid) + 1);
1128 
1129  if (ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
1130  return -1;
1131  }
1132 
1133  return 0;
1134 }
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1100
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:936

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

Referenced by chan_pjsip_indicate().

◆ 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 719 of file chan_pjsip.c.

720 {
721  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
722  struct ast_sip_session *session;
723  struct answer_data ans_data = { 0, };
724  int res;
725  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
726 
727  if (ast_channel_state(ast) == AST_STATE_UP) {
728  SCOPE_EXIT_RTN_VALUE(0, "Already up\n");
729  return 0;
730  }
731 
733  session = ao2_bump(channel->session);
734 
735  /* the answer task needs to be pushed synchronously otherwise a race condition
736  can occur between this thread and bridging (specifically when native bridging
737  attempts to do direct media) */
738  ast_channel_unlock(ast);
739  ans_data.session = session;
740  ans_data.indent = ast_trace_get_indent();
741  res = ast_sip_push_task_wait_serializer(session->serializer, answer, &ans_data);
742  if (res) {
743  if (res == -1) {
744  ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
745  ast_channel_name(session->channel));
746  }
747  ao2_ref(session, -1);
748  ast_channel_lock(ast);
749  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
750  }
751  ao2_ref(session, -1);
752  ast_channel_lock(ast);
753 
755 }
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static int answer(void *data)
Definition: chan_pjsip.c:675
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7469
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
Definition: res_pjsip.c:2013
#define ast_trace_get_indent()
struct ast_sip_session * session
Pointer to session.

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, answer_data::indent, LOG_ERROR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, answer_data::session, ast_sip_channel_pvt::session, and session.

◆ 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 2406 of file chan_pjsip.c.

2407 {
2408  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2409  SCOPE_ENTER(1, "%s Topology: %s\n", ast_sip_session_get_name(channel->session),
2411 
2412  ao2_ref(channel, +1);
2413  if (ast_sip_push_task(channel->session->serializer, call, channel)) {
2414  ast_log(LOG_WARNING, "Error attempting to place outbound call to '%s'\n", dest);
2415  ao2_cleanup(channel);
2416  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
2417  }
2418 
2419  SCOPE_EXIT_RTN_VALUE(0, "'call' task pushed\n");
2420 }
static int call(void *data)
Definition: chan_pjsip.c:2379
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:1933
struct ast_stream_topology * topology
The media stream topology.
struct ast_sip_session_media_state * pending_media_state
struct ast_taskprocessor * serializer

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.

◆ 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 758 of file chan_pjsip.c.

760 {
761  const char *target_context;
762  int exists;
763  int dsp_features;
764 
765  dsp_features = ast_dsp_get_features(session->dsp);
766  dsp_features &= ~DSP_FEATURE_FAX_DETECT;
767  if (dsp_features) {
768  ast_dsp_set_features(session->dsp, dsp_features);
769  } else {
770  ast_dsp_free(session->dsp);
771  session->dsp = NULL;
772  }
773 
774  /* If already executing in the fax extension don't do anything */
775  if (!strcmp(ast_channel_exten(ast), "fax")) {
776  return f;
777  }
778 
779  target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
780 
781  /*
782  * We need to unlock the channel here because ast_exists_extension has the
783  * potential to start and stop an autoservice on the channel. Such action
784  * is prone to deadlock if the channel is locked.
785  *
786  * ast_async_goto() has its own restriction on not holding the channel lock.
787  */
788  ast_channel_unlock(ast);
789  ast_frfree(f);
790  f = &ast_null_frame;
791  exists = ast_exists_extension(ast, target_context, "fax", 1,
792  S_COR(ast_channel_caller(ast)->id.number.valid,
793  ast_channel_caller(ast)->id.number.str, NULL));
794  if (exists) {
795  ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n",
796  ast_channel_name(ast));
797  pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
798  if (ast_async_goto(ast, target_context, "fax", 1)) {
799  ast_log(LOG_ERROR, "Failed to async goto '%s' into fax extension in '%s'\n",
800  ast_channel_name(ast), target_context);
801  }
802  } else {
803  ast_log(LOG_NOTICE, "FAX CNG detected on '%s' but no fax extension in '%s'\n",
804  ast_channel_name(ast), target_context);
805  }
806 
807  /* It's possible for a masquerade to have occurred when doing the ast_async_goto resulting in
808  * the channel on the session having changed. Since we need to return with the original channel
809  * locked we lock the channel that was passed in and not session->channel.
810  */
811  ast_channel_lock(ast);
812 
813  return f;
814 }
const char * ast_channel_context(const struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
const char * ast_channel_macrocontext(const struct ast_channel *chan)
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1773
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1767
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1758
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_logic.c:124
#define ast_frfree(fr)
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define ast_verb(level,...)
#define LOG_NOTICE
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:4182
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.
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.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
#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:87
Number structure.
Definition: app_followme.c:154

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, DSP_FEATURE_FAX_DETECT, exists(), LOG_ERROR, LOG_NOTICE, NULL, pbx_builtin_setvar_helper(), S_COR, S_OR, and session.

Referenced by chan_pjsip_read_stream().

◆ 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 1167 of file chan_pjsip.c.

1168 {
1169  RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", data), ao2_cleanup);
1171  RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, NULL, ao2_cleanup);
1172  struct ast_devstate_aggregate aggregate;
1173  int num, inuse = 0;
1174 
1175  if (!endpoint) {
1176  return AST_DEVICE_INVALID;
1177  }
1178 
1179  endpoint_snapshot = ast_endpoint_latest_snapshot(ast_endpoint_get_tech(endpoint->persistent),
1180  ast_endpoint_get_resource(endpoint->persistent));
1181 
1182  if (!endpoint_snapshot) {
1183  return AST_DEVICE_INVALID;
1184  }
1185 
1186  if (endpoint_snapshot->state == AST_ENDPOINT_OFFLINE) {
1188  } else if (endpoint_snapshot->state == AST_ENDPOINT_ONLINE) {
1190  }
1191 
1192  if (!endpoint_snapshot->num_channels) {
1193  return state;
1194  }
1195 
1196  ast_devstate_aggregate_init(&aggregate);
1197 
1198  for (num = 0; num < endpoint_snapshot->num_channels; num++) {
1199  struct ast_channel_snapshot *snapshot;
1200 
1201  snapshot = ast_channel_snapshot_get_latest(endpoint_snapshot->channel_ids[num]);
1202  if (!snapshot) {
1203  continue;
1204  }
1205 
1206  if (chan_pjsip_get_hold(snapshot->base->uniqueid)) {
1208  } else {
1209  ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
1210  }
1211 
1212  if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
1213  (snapshot->state == AST_STATE_BUSY)) {
1214  inuse++;
1215  }
1216 
1217  ao2_ref(snapshot, -1);
1218  }
1219 
1220  if (endpoint->devicestate_busy_at && (inuse == endpoint->devicestate_busy_at)) {
1222  } else if (ast_devstate_aggregate_result(&aggregate) != AST_DEVICE_INVALID) {
1223  state = ast_devstate_aggregate_result(&aggregate);
1224  }
1225 
1226  return state;
1227 }
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:1154
enum sip_cc_notify_state state
Definition: chan_sip.c:966
@ AST_STATE_RING
Definition: channelstate.h:40
@ AST_STATE_BUSY
Definition: channelstate.h:43
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
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
Definition: devicestate.c:630
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
Definition: devicestate.c:663
enum ast_device_state ast_state_chan2dev(enum ast_channel_state chanstate)
Convert channel state to devicestate.
Definition: devicestate.c:242
ast_device_state
Device States.
Definition: devicestate.h:52
@ AST_DEVICE_UNKNOWN
Definition: devicestate.h:53
@ AST_DEVICE_ONHOLD
Definition: devicestate.h:61
@ AST_DEVICE_INVALID
Definition: devicestate.h:57
@ AST_DEVICE_BUSY
Definition: devicestate.h:56
@ AST_DEVICE_NOT_INUSE
Definition: devicestate.h:54
@ AST_DEVICE_UNAVAILABLE
Definition: devicestate.h:58
@ AST_ENDPOINT_OFFLINE
Definition: endpoints.h:55
@ AST_ENDPOINT_ONLINE
Definition: endpoints.h:57
const char * ast_endpoint_get_tech(const struct ast_endpoint *endpoint)
Gets the technology of the given endpoint.
const char * ast_endpoint_get_resource(const struct ast_endpoint *endpoint)
Gets the resource name of the given endpoint.
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_endpoint_snapshot * ast_endpoint_latest_snapshot(const char *tech, const char *resource)
Retrieve the most recent snapshot for the endpoint with the given name.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
const ast_string_field uniqueid
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
enum ast_channel_state state
You shouldn't care about the contents of this struct.
Definition: devicestate.h:228
A snapshot of an endpoint's state.
An entity with which Asterisk communicates.
Definition: res_pjsip.h:854

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_sip_endpoint::devicestate_busy_at, ast_devstate_aggregate::inuse, NULL, ast_sip_endpoint::persistent, RAII_VAR, state, ast_channel_snapshot::state, and ast_channel_snapshot_base::uniqueid.

◆ 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 2171 of file chan_pjsip.c.

2172 {
2173  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2174  struct ast_sip_session_media *media;
2175 
2177 
2178  switch (channel->session->dtmf) {
2179  case AST_SIP_DTMF_RFC_4733:
2180  if (!media || !media->rtp) {
2181  return 0;
2182  }
2183 
2185  break;
2186  case AST_SIP_DTMF_AUTO:
2187  if (!media || !media->rtp) {
2188  return 0;
2189  }
2190 
2192  return -1;
2193  }
2194 
2196  break;
2198  if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) {
2199  return 0;
2200  }
2202  break;
2203  case AST_SIP_DTMF_NONE:
2204  break;
2205  case AST_SIP_DTMF_INBAND:
2206  return -1;
2207  default:
2208  break;
2209  }
2210 
2211  return 0;
2212 }
char digit
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_SIP_DTMF_NONE
Definition: res_pjsip.h:429
@ AST_SIP_DTMF_AUTO_INFO
Definition: res_pjsip.h:440
@ AST_SIP_DTMF_AUTO
Definition: res_pjsip.h:438
@ AST_SIP_DTMF_INBAND
Definition: res_pjsip.h:434
@ AST_SIP_DTMF_RFC_4733
Definition: res_pjsip.h:432
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2129
@ AST_RTP_DTMF_MODE_INBAND
Definition: rtp_engine.h:154
@ AST_RTP_DTMF_MODE_NONE
Definition: rtp_engine.h:150
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2073
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
struct ast_sip_session_media_state * active_media_state
enum ast_sip_dtmf_mode dtmf

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, digit, ast_sip_session::dtmf, ast_sip_session_media::rtp, and ast_sip_channel_pvt::session.

◆ 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 2283 of file chan_pjsip.c.

2284 {
2285  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2286  struct ast_sip_session_media *media;
2287 
2288  if (!channel || !channel->session) {
2289  /* This happens when the channel is hungup while a DTMF digit is playing. See ASTERISK-28086 */
2290  ast_debug(3, "Channel %s disappeared while calling digit_end\n", ast_channel_name(ast));
2291  return -1;
2292  }
2293 
2295 
2296  switch (channel->session->dtmf) {
2298  {
2299  if (!media || !media->rtp) {
2300  return 0;
2301  }
2302 
2304  ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));
2306  break;
2307  }
2308  /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */
2309  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));
2310  }
2311 
2312  case AST_SIP_DTMF_INFO:
2313  {
2314  struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
2315 
2316  if (!dtmf_data) {
2317  return -1;
2318  }
2319 
2320  if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
2321  ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
2322  ao2_cleanup(dtmf_data);
2323  return -1;
2324  }
2325  break;
2326  }
2327  case AST_SIP_DTMF_RFC_4733:
2328  if (!media || !media->rtp) {
2329  return 0;
2330  }
2331 
2333  break;
2334  case AST_SIP_DTMF_AUTO:
2335  if (!media || !media->rtp) {
2336  return 0;
2337  }
2338 
2340  return -1;
2341  }
2342 
2344  break;
2345  case AST_SIP_DTMF_NONE:
2346  break;
2347  case AST_SIP_DTMF_INBAND:
2348  return -1;
2349  }
2350 
2351  return 0;
2352 }
static int transmit_info_dtmf(void *data)
Definition: chan_pjsip.c:2239
static struct info_dtmf_data * info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
Definition: chan_pjsip.c:2226
#define ast_debug(level,...)
Log a DEBUG message.
@ AST_SIP_DTMF_INFO
Definition: res_pjsip.h:436
int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
Definition: rtp_engine.c:2101
unsigned int duration
Definition: chan_pjsip.c:2217

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, digit, ast_sip_session::dtmf, info_dtmf_data::duration, info_dtmf_data_alloc(), LOG_WARNING, ast_sip_session_media::rtp, ast_sip_session::serializer, ast_sip_channel_pvt::session, and transmit_info_dtmf().

◆ 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 1038 of file chan_pjsip.c.

1039 {
1040  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(newchan);
1041 
1042  if (channel->session->channel != oldchan) {
1043  return -1;
1044  }
1045 
1046  /*
1047  * The masquerade has suspended the channel's session
1048  * serializer so we can safely change it outside of
1049  * the serializer thread.
1050  */
1051  channel->session->channel = newchan;
1052 
1054 
1055  return 0;
1056 }

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

◆ 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 244 of file chan_pjsip.c.

245 {
246  SCOPE_ENTER(1, "%s Native formats %s\n", ast_channel_name(chan),
249  SCOPE_EXIT_RTN();
250 }
static PGresult * result
Definition: cel_pgsql.c:84
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
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:734
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
#define SCOPE_EXIT_RTN(...)

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, result, SCOPE_ENTER, and SCOPE_EXIT_RTN.

◆ 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 1154 of file chan_pjsip.c.

1155 {
1156  RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1157 
1158  hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1159  if (!hold_uid) {
1160  return 0;
1161  }
1162 
1163  return 1;
1164 }

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

Referenced by chan_pjsip_devicestate().

◆ 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 162 of file chan_pjsip.c.

172 {
173  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
174  struct ast_sip_endpoint *endpoint;
175  struct ast_datastore *datastore;
176  struct ast_sip_session_media *media;
177 
178  if (!channel || !channel->session) {
180  }
181 
182  /* XXX Getting the first RTP instance for direct media related stuff seems just
183  * absolutely wrong. But the native RTP bridge knows no other method than single-stream
184  * for direct media. So this is the best we can do.
185  */
187  if (!media || !media->rtp) {
189  }
190 
191  datastore = ast_sip_session_get_datastore(channel->session, "t38");
192  if (datastore) {
193  ao2_ref(datastore, -1);
195  }
196 
197  endpoint = channel->session->endpoint;
198 
199  *instance = media->rtp;
200  ao2_ref(*instance, +1);
201 
202  ast_assert(endpoint != NULL);
203  if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
205  }
206 
207  if (endpoint->media.direct_media.enabled) {
209  }
210 
212 }
@ AST_SIP_MEDIA_ENCRYPT_NONE
Definition: res_pjsip.h:529
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
@ AST_RTP_GLUE_RESULT_LOCAL
Definition: rtp_engine.h:164
@ AST_RTP_GLUE_RESULT_REMOTE
Definition: rtp_engine.h:162
@ AST_RTP_GLUE_RESULT_FORBID
Definition: rtp_engine.h:160
Structure for a data store object.
Definition: datastore.h:64
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:806
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:808
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:887
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:749
struct ast_sip_endpoint * endpoint
#define ast_assert(a)
Definition: utils.h:734

◆ chan_pjsip_get_uniqueid()

static const char * chan_pjsip_get_uniqueid ( struct ast_channel ast)
static

Definition at line 1271 of file chan_pjsip.c.

1272 {
1273  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1275 
1276  if (!uniqueid) {
1277  return "";
1278  }
1279 
1280  ast_copy_pj_str(uniqueid, &channel->session->inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
1281 
1282  return uniqueid;
1283 }
#define UNIQUEID_BUFSIZE
Definition: chan_pjsip.c:76
static struct ast_threadstorage uniqueid_threadbuf
Definition: chan_pjsip.c:75
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:2035
struct pjsip_inv_session * inv_session
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.

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.

◆ 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 162 of file chan_pjsip.c.

216 {
217  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
218  struct ast_sip_endpoint *endpoint;
219  struct ast_sip_session_media *media;
220 
221  if (!channel || !channel->session) {
223  }
224 
226  if (!media || !media->rtp) {
228  }
229 
230  endpoint = channel->session->endpoint;
231 
232  *instance = media->rtp;
233  ao2_ref(*instance, +1);
234 
235  ast_assert(endpoint != NULL);
236  if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
238  }
239 
241 }
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33

◆ 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 2537 of file chan_pjsip.c.

2538 {
2539  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2540  int cause;
2541  struct hangup_data *h_data;
2542  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2543 
2544  if (!channel || !channel->session) {
2545  SCOPE_EXIT_RTN_VALUE(-1, "No channel or session\n");
2546  }
2547 
2549  h_data = hangup_data_alloc(cause, ast);
2550 
2551  if (!h_data) {
2552  goto failure;
2553  }
2554 
2555  if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
2556  ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
2557  goto failure;
2558  }
2559 
2560  SCOPE_EXIT_RTN_VALUE(0, "Cause: %d\n", cause);
2561 
2562 failure:
2563  /* Go ahead and do our cleanup of the session and channel even if we're not going
2564  * to be able to send our SIP request/response
2565  */
2566  clear_session_and_channel(channel->session, ast);
2567  ao2_cleanup(channel);
2568  ao2_cleanup(h_data);
2569 
2570  SCOPE_EXIT_RTN_VALUE(-1, "Cause: %d\n", cause);
2571 }
static int hangup_cause2sip(int cause)
Internal function which translates from Asterisk cause codes to SIP response codes.
Definition: chan_pjsip.c:2423
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:2497
static struct hangup_data * hangup_data_alloc(int cause, struct ast_channel *chan)
Definition: chan_pjsip.c:2482
static int hangup(void *data)
Definition: chan_pjsip.c:2504
int ast_channel_hangupcause(const struct ast_channel *chan)

References ao2_cleanup, ast_channel_hangupcause(), ast_channel_name(), ast_channel_tech_pvt(), ast_log, ast_sip_push_task(), hangup_data::cause, 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.

◆ chan_pjsip_incoming_ack()

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

Definition at line 3262 of file chan_pjsip.c.

3263 {
3265 
3266  if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
3267  if (session->endpoint->media.direct_media.enabled && session->channel) {
3268  ast_trace(-1, "%s: Queueing SRCCHANGE\n", ast_sip_session_get_name(session));
3270  }
3271  }
3273 }
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1225
@ AST_CONTROL_SRCCHANGE
#define ast_trace(level,...)

References AST_CONTROL_SRCCHANGE, ast_queue_control(), ast_sip_session_get_name(), ast_trace, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and session.

◆ 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 3028 of file chan_pjsip.c.

3029 {
3030  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
3031  struct transport_info_data *transport_data;
3032  pjsip_tx_data *packet = NULL;
3034 
3035  if (session->channel) {
3036  SCOPE_EXIT_RTN_VALUE(0, "%s: No channel\n", ast_sip_session_get_name(session));
3037  }
3038 
3039  /* Check for a to-tag to determine if this is a reinvite */
3040  if (rdata->msg_info.to->tag.slen) {
3041  /* Weird case. We've received a reinvite but we don't have a channel. The most
3042  * typical case for this happening is that a blind transfer fails, and so the
3043  * transferer attempts to reinvite himself back into the call. We already got
3044  * rid of that channel, and the other side of the call is unrecoverable.
3045  *
3046  * We treat this as a failure, so our best bet is to just hang this call
3047  * up and not create a new channel. Clearing defer_terminate here ensures that
3048  * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
3049  */
3050  session->defer_terminate = 0;
3052  SCOPE_EXIT_RTN_VALUE(-1, "%s: We have a To tag but no channel. Terminating session\n", ast_sip_session_get_name(session));
3053  }
3054 
3055  datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
3056  if (!datastore) {
3057  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info datastore\n", ast_sip_session_get_name(session));
3058  }
3059 
3060  transport_data = ast_calloc(1, sizeof(*transport_data));
3061  if (!transport_data) {
3062  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info\n", ast_sip_session_get_name(session));
3063  }
3064  pj_sockaddr_cp(&transport_data->local_addr, &rdata->tp_info.transport->local_addr);
3065  pj_sockaddr_cp(&transport_data->remote_addr, &rdata->pkt_info.src_addr);
3066  datastore->data = transport_data;
3068 
3069  if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
3070  if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS
3071  && packet) {
3073  }
3074 
3075  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Failed to allocate new PJSIP channel on incoming SIP INVITE\n",
3077  }
3078 
3080 
3081  /* channel gets created on incoming request, but we wait to call start
3082  so other supplements have a chance to run */
3084 }
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
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:261
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:539
static void set_sipdomain_variable(struct ast_sip_session *session)
Definition: chan_pjsip.c:3015
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
Transport information stored in transport_info datastore.
Definition: chan_pjsip.h:30
pj_sockaddr local_addr
Our address that received the request.
Definition: chan_pjsip.h:34
pj_sockaddr remote_addr
The address that sent the request.
Definition: chan_pjsip.h:32

References ao2_cleanup, ast_calloc, 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_datastore::data, transport_info_data::local_addr, LOG_ERROR, NULL, RAII_VAR, transport_info_data::remote_addr, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, session, set_sipdomain_variable(), and transport_info.

◆ 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 3207 of file chan_pjsip.c.

3208 {
3209  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3210  SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3211 
3212  if (!session->channel) {
3213  SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3214  }
3215 
3216  switch (status.code) {
3217  case 180: {
3218  pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3219  if (sdp && sdp->body.ptr) {
3220  ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3222  } else {
3223  ast_trace(-1, "%s: Queueing RINGING\n", ast_sip_session_get_name(session));
3225  }
3226 
3227  ast_channel_lock(session->channel);
3228  if (ast_channel_state(session->channel) != AST_STATE_UP) {
3230  }
3231  ast_channel_unlock(session->channel);
3232  break;
3233  }
3234  case 183:
3235  if (session->endpoint->ignore_183_without_sdp) {
3236  pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3237  if (sdp && sdp->body.ptr) {
3238  ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3239  ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS with SDP\n", ast_sip_session_get_name(session),
3240  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3242  }
3243  } else {
3244  ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3245  ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS without SDP\n", ast_sip_session_get_name(session),
3246  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3248  }
3249  break;
3250  case 200:
3251  ast_trace(-1, "%s: Queueing ANSWER\n", ast_sip_session_get_name(session));
3253  break;
3254  default:
3255  ast_trace(-1, "%s: Not queueing anything\n", ast_sip_session_get_name(session));
3256  break;
3257  }
3258 
3260 }
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING

References ast_channel_lock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_queue_control(), ast_setstate(), ast_sip_session_get_name(), AST_STATE_RINGING, AST_STATE_UP, ast_trace, SCOPE_ENTER, SCOPE_EXIT_RTN, session, and status.

◆ chan_pjsip_incoming_response_update_cause()

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

Function called when a response is received on the session.

Definition at line 3177 of file chan_pjsip.c.

3178 {
3179  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3180  struct ast_control_pvt_cause_code *cause_code;
3181  int data_size = sizeof(*cause_code);
3182  SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3183 
3184  if (!session->channel) {
3185  SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3186  }
3187 
3188  /* Build and send the tech-specific cause information */
3189  /* size of the string making up the cause code is "SIP " number + " " + reason length */
3190  data_size += 4 + 4 + pj_strlen(&status.reason);
3191  cause_code = ast_alloca(data_size);
3192  memset(cause_code, 0, data_size);
3193 
3195 
3196  snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
3197  (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
3198 
3199  cause_code->ast_cause = hangup_sip2cause(status.code);
3200  ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
3201  ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
3202 
3204 }
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
static int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_pjsip.c:2881
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:1232
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:4381
#define AST_CHANNEL_NAME
Definition: channel.h:171
@ AST_CONTROL_PVT_CAUSE_CODE
char chan_name[AST_CHANNEL_NAME]

References ast_alloca, ast_control_pvt_cause_code::ast_cause, ast_channel_hangupcause_hash_set(), AST_CHANNEL_NAME, ast_channel_name(), AST_CONTROL_PVT_CAUSE_CODE, ast_copy_string(), ast_queue_control_data(), ast_sip_session_get_name(), ast_control_pvt_cause_code::chan_name, ast_control_pvt_cause_code::code, hangup_sip2cause(), SCOPE_ENTER, SCOPE_EXIT_RTN, session, and status.

◆ 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 1609 of file chan_pjsip.c.

1610 {
1611  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1612  struct ast_sip_session_media *media;
1613  int response_code = 0;
1614  int res = 0;
1615  char *device_buf;
1616  size_t device_buf_size;
1617  int i;
1618  const struct ast_stream_topology *topology;
1619  struct ast_frame f = {
1621  .subclass = {
1622  .integer = condition
1623  },
1624  .datalen = datalen,
1625  .data.ptr = (void *)data,
1626  };
1627  char condition_name[256];
1628  unsigned int duration;
1629  char digit;
1630  struct info_dtmf_data *dtmf_data;
1631 
1632  SCOPE_ENTER(3, "%s: Indicated %s\n", ast_channel_name(ast),
1633  ast_frame_subclass2str(&f, condition_name, sizeof(condition_name), NULL, 0));
1634 
1635  switch (condition) {
1636  case AST_CONTROL_RINGING:
1637  if (ast_channel_state(ast) == AST_STATE_RING) {
1638  if (channel->session->endpoint->inband_progress ||
1639  (channel->session->inv_session && channel->session->inv_session->neg &&
1640  pjmedia_sdp_neg_get_state(channel->session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE)) {
1641  res = -1;
1643  response_code = 180;
1644  } else {
1645  response_code = 183;
1646  }
1647  } else {
1648  response_code = 180;
1649  }
1650  } else {
1651  res = -1;
1652  }
1654  break;
1655  case AST_CONTROL_BUSY:
1656  if (ast_channel_state(ast) != AST_STATE_UP) {
1657  response_code = 486;
1658  } else {
1659  res = -1;
1660  }
1661  break;
1663  if (ast_channel_state(ast) != AST_STATE_UP) {
1664  response_code = 503;
1665  } else {
1666  res = -1;
1667  }
1668  break;
1670  if (ast_channel_state(ast) != AST_STATE_UP) {
1671  response_code = 484;
1672  } else {
1673  res = -1;
1674  }
1675  break;
1677  if (ast_channel_state(ast) != AST_STATE_UP) {
1678  response_code = 100;
1679  } else {
1680  res = -1;
1681  }
1682  break;
1683  case AST_CONTROL_PROGRESS:
1684  if (ast_channel_state(ast) != AST_STATE_UP) {
1685  response_code = 183;
1686  } else {
1687  res = -1;
1688  }
1690  break;
1691  case AST_CONTROL_FLASH:
1692  duration = 300;
1693  digit = '!';
1694  dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
1695 
1696  if (!dtmf_data) {
1697  res = -1;
1698  break;
1699  }
1700 
1701  if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
1702  ast_log(LOG_WARNING, "Error sending FLASH via INFO on channel %s\n", ast_channel_name(ast));
1703  ao2_ref(dtmf_data, -1); /* dtmf_data can't be null here */
1704  res = -1;
1705  }
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);
1732  ao2_cleanup(channel->session);
1733  }
1734  }
1735  ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
1736  } else {
1737  ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
1738  res = -1;
1739  }
1740  }
1741  /* XXX If there were no video streams, then this should set
1742  * res to -1
1743  */
1744  break;
1746  ao2_ref(channel->session, +1);
1748  ao2_cleanup(channel->session);
1749  }
1750  break;
1752  break;
1754  res = -1;
1755  break;
1757  ast_assert(datalen == sizeof(int));
1758  if (*(int *) data) {
1759  /*
1760  * Masquerade is beginning:
1761  * Wait for session serializer to get suspended.
1762  */
1763  ast_channel_unlock(ast);
1764  ast_sip_session_suspend(channel->session);
1765  ast_channel_lock(ast);
1766  } else {
1767  /*
1768  * Masquerade is complete:
1769  * Unsuspend the session serializer.
1770  */
1772  }
1773  break;
1774  case AST_CONTROL_HOLD:
1776  device_buf_size = strlen(ast_channel_name(ast)) + 1;
1777  device_buf = alloca(device_buf_size);
1778  ast_channel_get_device_name(ast, device_buf, device_buf_size);
1780  if (!channel->session->moh_passthrough) {
1781  ast_moh_start(ast, data, NULL);
1782  } else {
1784  ast_log(LOG_WARNING, "Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
1786  ao2_ref(channel->session, -1);
1787  }
1788  }
1789  break;
1790  case AST_CONTROL_UNHOLD:
1792  device_buf_size = strlen(ast_channel_name(ast)) + 1;
1793  device_buf = alloca(device_buf_size);
1794  ast_channel_get_device_name(ast, device_buf, device_buf_size);
1796  if (!channel->session->moh_passthrough) {
1797  ast_moh_stop(ast);
1798  } else {
1800  ast_log(LOG_WARNING, "Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
1802  ao2_ref(channel->session, -1);
1803  }
1804  }
1805  break;
1806  case AST_CONTROL_SRCUPDATE:
1807  break;
1808  case AST_CONTROL_SRCCHANGE:
1809  break;
1811  if (ast_channel_state(ast) != AST_STATE_UP) {
1812  response_code = 181;
1813  } else {
1814  res = -1;
1815  }
1816  break;
1818  res = 0;
1819 
1820  if (channel->session->t38state == T38_PEER_REINVITE) {
1821  const struct ast_control_t38_parameters *parameters = data;
1822 
1823  if (parameters->request_response == AST_T38_REQUEST_PARMS) {
1824  res = AST_T38_REQUEST_PARMS;
1825  }
1826  }
1827 
1828  break;
1830  topology = data;
1831  ast_trace(-1, "%s: New topology: %s\n", ast_channel_name(ast),
1832  ast_str_tmp(256, ast_stream_topology_to_str(topology, &STR_TMP)));
1833  res = handle_topology_request_change(channel->session, topology);
1834  break;
1836  break;
1838  break;
1839  case -1:
1840  res = -1;
1841  break;
1842  default:
1843  ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
1844  res = -1;
1845  break;
1846  }
1847 
1848  if (response_code) {
1849  struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
1850 
1851  if (!ind_data) {
1852  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
1853  }
1854 
1855  if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
1856  ast_log(LOG_ERROR, "%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
1858  ao2_cleanup(ind_data);
1859  res = -1;
1860  }
1861  }
1862 
1863  SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_channel_name(ast));
1864 }
static int update_connected_line_information(void *data)
Update connected line information.
Definition: chan_pjsip.c:1422
static int remote_send_unhold(void *data)
Update local hold state to be unheld.
Definition: chan_pjsip.c:1499
static int handle_topology_request_change(struct ast_sip_session *session, const struct ast_stream_topology *proposed)
Definition: chan_pjsip.c:1585
static int indicate(void *data)
Definition: chan_pjsip.c:1326
static int remote_send_hold(void *data)
Update local hold state to be held.
Definition: chan_pjsip.c:1493
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:1141
static int transmit_info_with_vidupdate(void *data)
Send SIP INFO with video update request.
Definition: chan_pjsip.c:1344
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:1301
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:1110
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:10682
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
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
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
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
struct ast_format * ast_format_h264
Built-in cached h264 format.
Definition: format_cache.c:176
struct ast_format * ast_format_h265
Built-in cached h265 format.
Definition: format_cache.c:181
struct ast_format * ast_format_vp9
Built-in cached vp9 format.
Definition: format_cache.c:196
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:191
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:581
@ AST_T38_REQUEST_PARMS
@ AST_FRAME_CONTROL
char * ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
Copy the discription of a frame's subclass into the provided string.
Definition: main/frame.c:406
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_HOLD
@ AST_CONTROL_STREAM_TOPOLOGY_CHANGED
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_FLASH
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_UPDATE_RTP_PEER
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:7849
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7859
unsigned int ast_sip_get_allow_sending_180_after_183(void)
Retrieve the global setting 'allow_sending_180_after_183'.
void ast_sip_session_unsuspend(struct ast_sip_session *session)
Request the session serializer be unsuspended.
void ast_sip_session_suspend(struct ast_sip_session *session)
Request and wait for the session serializer to be suspended.
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
@ T38_PEER_REINVITE
Definition: sip.h:665
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
enum ast_control_t38 request_response
Data structure associated with a single frame of data.
union ast_frame::@254 data
enum ast_frame_type frametype
unsigned int inband_progress
Definition: res_pjsip.h:909
struct ast_sip_session_media_state::@293 sessions
Mapping of stream to media sessions.
enum ast_media_type type
Media type of this session media.
enum ast_sip_session_t38state t38state
unsigned int moh_passthrough
size_t datalen
Definition: chan_pjsip.c:1290
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

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_FLASH, 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_get_allow_sending_180_after_183(), ast_sip_push_task(), ast_sip_session_suspend(), ast_sip_session_unsuspend(), ast_sorcery_object_get_id(), AST_STATE_RING, AST_STATE_UP, ast_str_tmp, ast_stream_topology_to_str(), AST_T38_REQUEST_PARMS, ast_test_suite_event_notify, ast_trace, AST_VECTOR_GET, AST_VECTOR_SIZE, chan_pjsip_add_hold(), chan_pjsip_remove_hold(), indicate_data::condition, ast_frame::data, indicate_data::datalen, ast_frame::datalen, digit, info_dtmf_data::duration, ast_sip_session::endpoint, ast_frame::frametype, handle_topology_request_change(), ast_sip_endpoint::inband_progress, indicate(), indicate_data_alloc(), info_dtmf_data_alloc(), ast_frame_subclass::integer, ast_sip_session::inv_session, LOG_ERROR, LOG_WARNING, ast_sip_endpoint::media, ast_sip_session::moh_passthrough, NULL, remote_send_hold(), remote_send_unhold(), ast_control_t38_parameters::request_response, indicate_data::response_code, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, ast_sip_session::serializer, ast_sip_channel_pvt::session, ast_sip_session_media_state::sessions, ast_frame::subclass, T38_PEER_REINVITE, ast_sip_session::t38state, transmit_info_dtmf(), transmit_info_with_vidupdate(), ast_sip_session_media::type, update_connected_line_information(), and ast_sip_endpoint_media_configuration::webrtc.

◆ 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 539 of file chan_pjsip.c.

540 {
541  struct ast_channel *chan;
542  struct ast_format_cap *caps;
543  RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
544  struct ast_sip_channel_pvt *channel;
545  struct ast_variable *var;
546  struct ast_stream_topology *topology;
548 
549  if (!(pvt = ao2_alloc_options(sizeof(*pvt), chan_pjsip_pvt_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK))) {
550  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt\n");
551  }
552 
554  S_COR(session->id.number.valid, session->id.number.str, ""),
555  S_COR(session->id.name.valid, session->id.name.str, ""),
556  session->endpoint->accountcode,
557  exten, session->endpoint->context,
558  assignedids, requestor, 0,
559  session->endpoint->persistent, "PJSIP/%s-%08x",
561  (unsigned) ast_atomic_fetchadd_int((int *) &chan_idx, +1));
562  if (!chan) {
563  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
564  }
565 
567 
568  if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
569  ast_channel_unlock(chan);
570  ast_hangup(chan);
571  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt channel\n");
572  }
573 
574  ast_channel_tech_pvt_set(chan, channel);
575 
576  if (!ast_stream_topology_get_count(session->pending_media_state->topology) ||
577  !compatible_formats_exist(session->pending_media_state->topology, session->endpoint->media.codecs)) {
579  if (!caps) {
580  ast_channel_unlock(chan);
581  ast_hangup(chan);
582  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create caps\n");
583  }
584  ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN);
585  topology = ast_stream_topology_clone(session->endpoint->media.topology);
586  } else {
587  caps = ast_stream_topology_get_formats(session->pending_media_state->topology);
588  topology = ast_stream_topology_clone(session->pending_media_state->topology);
589  }
590 
591  if (!topology || !caps) {
592  ao2_cleanup(caps);
593  ast_stream_topology_free(topology);
594  ast_channel_unlock(chan);
595  ast_hangup(chan);
596  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't get caps or clone topology\n");
597  }
598 
600 
601  ast_channel_nativeformats_set(chan, caps);
602  ast_channel_set_stream_topology(chan, topology);
603 
604  if (!ast_format_cap_empty(caps)) {
605  struct ast_format *fmt;
606 
608  if (!fmt) {
609  /* Since our capabilities aren't empty, this will succeed */
610  fmt = ast_format_cap_get_format(caps, 0);
611  }
612  ast_channel_set_writeformat(chan, fmt);
614  ast_channel_set_readformat(chan, fmt);
616  ao2_ref(fmt, -1);
617  }
618 
619  ao2_ref(caps, -1);
620 
621  if (state == AST_STATE_RING) {
622  ast_channel_rings_set(chan, 1);
623  }
624 
626 
627  ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id);
628  ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id);
629  ast_channel_caller(chan)->ani2 = session->ani2;
630 
631  if (!ast_strlen_zero(exten)) {
632  /* Set provided DNID on the new channel. */
634  }
635 
636  ast_channel_priority_set(chan, 1);
637 
638  ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
639  ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup);
640 
641  ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups);
642  ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups);
643 
644  if (!ast_strlen_zero(session->endpoint->language)) {
645  ast_channel_language_set(chan, session->endpoint->language);
646  }
647 
648  if (!ast_strlen_zero(session->endpoint->zone)) {
649  struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
650  if (!zone) {
651  ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
652  }
653  ast_channel_zone_set(chan, zone);
654  }
655 
656  for (var = session->endpoint->channel_vars; var; var = var->next) {
657  char buf[512];
659  var->value, buf, sizeof(buf)));
660  }
661 
663  ast_channel_unlock(chan);
664 
666 
667  SCOPE_EXIT_RTN_VALUE(chan);
668 }
#define var
Definition: ast_expr2f.c:614
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:122
static void chan_pjsip_pvt_dtor(void *obj)
Definition: chan_pjsip.c:82
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
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:518
static unsigned int chan_idx
Definition: chan_pjsip.c:80
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.
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
#define ast_channel_alloc_with_endpoint(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint,...)
Definition: channel.h:1262
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:871
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
void ast_channel_set_readformat(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:1759
void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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:744
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
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
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 ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
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:3222
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:433
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
struct ast_sip_channel_pvt * ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session)
Allocate a new SIP channel pvt structure.
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
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:930
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:433
struct ast_party_dialed::@236 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:386
A set of tones for a given locale.
Definition: indications.h:74
Structure for variables, used for configurations and for channel variables.
The PJSIP channel driver pvt, stored in the ast_sip_channel_pvt data structure.
Definition: chan_pjsip.h:42

References ast_party_caller::ani2, 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, chan_idx, chan_pjsip_pvt_dtor(), chan_pjsip_tech, compatible_formats_exist(), exten, LOG_ERROR, NULL, ast_party_dialed::number, pbx_builtin_setvar_helper(), RAII_VAR, S_COR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, set_channel_on_rtp_instance(), ast_party_dialed::str, and var.

Referenced by chan_pjsip_incoming_request(), and chan_pjsip_request_with_stream_topology().

◆ chan_pjsip_pvt_dtor()

static void chan_pjsip_pvt_dtor ( void *  obj)
static

Definition at line 82 of file chan_pjsip.c.

83 {
84 }

Referenced by chan_pjsip_new().

◆ 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 1230 of file chan_pjsip.c.

1231 {
1232  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1233  int res = -1;
1235 
1236  if (!channel) {
1237  return -1;
1238  }
1239 
1240  switch (option) {
1241  case AST_OPTION_T38_STATE:
1242  if (channel->session->endpoint->media.t38.enabled) {
1243  switch (channel->session->t38state) {
1244  case T38_LOCAL_REINVITE:
1245  case T38_PEER_REINVITE:
1247  break;
1248  case T38_ENABLED:
1250  break;
1251  case T38_REJECTED:
1253  break;
1254  default:
1256  break;
1257  }
1258  }
1259 
1260  *((enum ast_t38_state *) data) = state;
1261  res = 0;
1262 
1263  break;
1264  default:
1265  break;
1266  }
1267 
1268  return res;
1269 }
#define T38_ENABLED
Definition: chan_ooh323.c:102
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:878
@ T38_STATE_UNAVAILABLE
Definition: channel.h:879
@ T38_STATE_UNKNOWN
Definition: channel.h:880
@ T38_STATE_REJECTED
Definition: channel.h:882
@ T38_STATE_NEGOTIATED
Definition: channel.h:883
@ T38_STATE_NEGOTIATING
Definition: channel.h:881
#define AST_OPTION_T38_STATE
@ T38_LOCAL_REINVITE
Definition: sip.h:664
@ T38_REJECTED
Definition: sip.h:667
struct ast_sip_t38_configuration t38
Definition: res_pjsip.h:810

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.

◆ 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 831 of file chan_pjsip.c.

832 {
833  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
834  struct ast_sip_session *session = channel->session;
835  struct ast_sip_session_media_read_callback_state *callback_state;
836  struct ast_frame *f;
837  int fdno = ast_channel_fdno(ast) - AST_EXTENDED_FDS;
838  struct ast_frame *cur;
839 
840  if (fdno >= AST_VECTOR_SIZE(&session->active_media_state->read_callbacks)) {
841  return &ast_null_frame;
842  }
843 
844  callback_state = AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, fdno);
845  f = callback_state->read_callback(session, callback_state->session);
846 
847  if (!f) {
848  return f;
849  }
850 
851  for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
852  if (cur->frametype == AST_FRAME_VOICE) {
853  break;
854  }
855  }
856 
857  if (!cur || callback_state->session != session->active_media_state->default_session[callback_state->session->type]) {
858  return f;
859  }
860 
861  session = channel->session;
862 
863  /*
864  * Asymmetric RTP only has one native format set at a time.
865  * Therefore we need to update the native format to the current
866  * raw read format BEFORE the native format check
867  */
868  if (!session->endpoint->asymmetric_rtp_codec &&
871  struct ast_format_cap *caps;
872 
873  /* For maximum compatibility we ensure that the formats match that of the received media */
874  ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n",
877 
879  if (caps) {
882  ast_format_cap_append(caps, cur->subclass.format, 0);
884  ao2_ref(caps, -1);
885  }
886 
889 
890  if (ast_channel_is_bridged(ast)) {
892  }
893  }
894 
897  ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n",
899  ast_frfree(f);
900  return &ast_null_frame;
901  }
902 
903  if (session->dsp) {
904  int dsp_features;
905 
906  dsp_features = ast_dsp_get_features(session->dsp);
907  if ((dsp_features & DSP_FEATURE_FAX_DETECT)
908  && session->endpoint->faxdetect_timeout
909  && session->endpoint->faxdetect_timeout <= ast_channel_get_up_time(ast)) {
910  dsp_features &= ~DSP_FEATURE_FAX_DETECT;
911  if (dsp_features) {
912  ast_dsp_set_features(session->dsp, dsp_features);
913  } else {
914  ast_dsp_free(session->dsp);
915  session->dsp = NULL;
916  }
917  ast_debug(3, "Channel driver fax CNG detection timeout on %s\n",
918  ast_channel_name(ast));
919  }
920  }
921  if (session->dsp) {
922  f = ast_dsp_process(ast, session->dsp, f);
923  if (f && (f->frametype == AST_FRAME_DTMF)) {
924  if (f->subclass.integer == 'f') {
925  ast_debug(3, "Channel driver fax CNG detected on %s\n",
926  ast_channel_name(ast));
928  /* When chan_pjsip_cng_tone_detected returns it is possible for the
929  * channel pointed to by ast and by session->channel to differ due to a
930  * masquerade. It's best not to touch things after this.
931  */
932  } else {
933  ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
934  ast_channel_name(ast));
935  }
936  }
937  }
938 
939  return f;
940 }
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:758
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.
Definition: chan_pjsip.c:817
#define AST_EXTENDED_FDS
Definition: channel.h:195
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.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
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:5565
int ast_channel_fdno(const struct ast_channel *chan)
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10731
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2846
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
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:5601
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:1497
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
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
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:523
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define AST_FRAME_DTMF
@ AST_FRAME_VOICE
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
struct ast_format * format
struct ast_frame_subclass subclass
Structure which contains read callback information.
ast_sip_session_media_read_cb read_callback
The callback to invoke.
struct ast_sip_session_media * session
The media session.
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668

References 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, chan_pjsip_cng_tone_detected(), ast_sip_session::channel, DSP_FEATURE_FAX_DETECT, 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, session, ast_frame::subclass, and ast_sip_session_media::type.

◆ 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 1141 of file chan_pjsip.c.

1142 {
1144 }
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_UNLINK
Definition: astobj2.h:1039

References ao2_find, OBJ_NODATA, OBJ_SEARCH_KEY, OBJ_UNLINK, and pjsip_uids_onhold.

Referenced by chan_pjsip_indicate(), and chan_pjsip_session_end().

◆ 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

Asterisk core interaction functions.

Definition at line 2715 of file chan_pjsip.c.

2716 {
2717  struct ast_stream_topology *topology;
2718  struct ast_channel *chan;
2719 
2721  if (!topology) {
2722  return NULL;
2723  }
2724 
2725  chan = chan_pjsip_request_with_stream_topology(type, topology, assignedids, requestor, data, cause);
2726 
2727  ast_stream_topology_free(topology);
2728 
2729  return chan;
2730 }
static const char type[]
Definition: chan_ooh323.c:109
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:2688
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:848
const char * data

References ast_stream_topology_create_from_format_cap(), ast_stream_topology_free(), chan_pjsip_request_with_stream_topology(), ast_channel::data, NULL, and type.

◆ 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 2688 of file chan_pjsip.c.

2689 {
2690  struct request_data req_data;
2692  SCOPE_ENTER(1, "%s Topology: %s\n", data,
2694 
2695  req_data.topology = topology;
2696  req_data.dest = data;
2697  /* Default failure value in case ast_sip_push_task_wait_servant() itself fails. */
2698  req_data.cause = AST_CAUSE_FAILURE;
2699 
2700  if (ast_sip_push_task_wait_servant(NULL, request, &req_data)) {
2701  *cause = req_data.cause;
2702  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't push task\n");
2703  }
2704 
2705  session = req_data.session;
2706 
2707  if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
2708  /* Session needs to be terminated prematurely */
2709  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
2710  }
2711 
2712  SCOPE_EXIT_RTN_VALUE(session->channel, "Channel: %s\n", ast_channel_name(session->channel));
2713 }
#define AST_CAUSE_FAILURE
Definition: causes.h:150
static int request(void *obj)
Definition: chan_pjsip.c:2580
@ AST_STATE_DOWN
Definition: channelstate.h:36
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:1999
struct ast_stream_topology * topology
Definition: chan_pjsip.c:2575

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(), request_data::dest, NULL, RAII_VAR, request(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, request_data::session, session, and request_data::topology.

Referenced by chan_pjsip_request().

◆ chan_pjsip_sendtext()

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

Definition at line 2858 of file chan_pjsip.c.

2859 {
2860  struct ast_msg_data *msg;
2861  int rc;
2862  struct ast_msg_data_attribute attrs[] =
2863  {
2864  {
2866  .value = (char *)text,
2867  }
2868  };
2869 
2871  if (!msg) {
2872  return -1;
2873  }
2874  rc = chan_pjsip_sendtext_data(ast, msg);
2875  ast_free(msg);
2876 
2877  return rc;
2878 }
char * text
Definition: app_queue.c:1641
#define ast_free(a)
Definition: astmm.h:180
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:2836
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.
@ AST_MSG_DATA_ATTR_BODY
Definition: message.h:458
@ AST_MSG_DATA_SOURCE_TYPE_UNKNOWN
Definition: message.h:447
enum ast_msg_data_attribute_type type
Definition: message.h:463
Structure used to transport a message through the frame core.
#define ARRAY_LEN(a)
Definition: utils.h:661

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

◆ 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 2836 of file chan_pjsip.c.

2837 {
2838  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2839  struct sendtext_data *data = sendtext_data_create(ast, msg);
2840 
2841  ast_debug(1, "Sending MESSAGE from '%s' to '%s:%s': %s\n",
2844  ast_channel_name(ast),
2846 
2847  if (!data) {
2848  return -1;
2849  }
2850 
2851  if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
2852  ao2_ref(data, -1);
2853  return -1;
2854  }
2855  return 0;
2856 }
static int sendtext(void *obj)
Definition: chan_pjsip.c:2765
static struct sendtext_data * sendtext_data_create(struct ast_channel *chan, struct ast_msg_data *msg)
Definition: chan_pjsip.c:2744
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.
@ AST_MSG_DATA_ATTR_TO
Definition: message.h:455
@ AST_MSG_DATA_ATTR_FROM
Definition: message.h:456
struct ast_msg_data * msg
Definition: chan_pjsip.c:2734

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

Referenced by chan_pjsip_sendtext().

◆ chan_pjsip_session_begin()

static void chan_pjsip_session_begin ( struct ast_sip_session session)
static

SIP session interaction functions.

Definition at line 2971 of file chan_pjsip.c.

2972 {
2973  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
2975 
2976  if (session->endpoint->media.direct_media.glare_mitigation ==
2978  SCOPE_EXIT_RTN("Direct media no glare mitigation\n");
2979  }
2980 
2982  "direct_media_glare_mitigation");
2983 
2984  if (!datastore) {
2985  SCOPE_EXIT_RTN("Couldn't create datastore\n");
2986  }
2987 
2989  SCOPE_EXIT_RTN();
2990 }
static struct ast_datastore_info direct_media_mitigation_info
Definition: chan_pjsip.c:266
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE
Definition: res_pjsip.h:514

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(), direct_media_mitigation_info, NULL, RAII_VAR, SCOPE_ENTER, SCOPE_EXIT_RTN, and 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 2993 of file chan_pjsip.c.

2994 {
2996 
2997  if (!session->channel) {
2998  SCOPE_EXIT_RTN("No channel\n");
2999  }
3000 
3002 
3003  ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
3004  if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
3005  int cause = hangup_sip2cause(session->inv_session->cause);
3006 
3007  ast_queue_hangup_with_cause(session->channel, cause);
3008  } else {
3009  ast_queue_hangup(session->channel);
3010  }
3011 
3012  SCOPE_EXIT_RTN();
3013 }
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1160

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(), hangup_sip2cause(), SCOPE_ENTER, SCOPE_EXIT_RTN, and session.

◆ 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 440 of file chan_pjsip.c.

446 {
447  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
448  struct ast_sip_session *session = channel->session;
450  SCOPE_ENTER(1, "%s %s\n", ast_channel_name(chan),
452 
453  /* Don't try to do any direct media shenanigans on early bridges */
454  if ((rtp || vrtp || tpeer) && !ast_channel_is_bridged(chan)) {
455  ast_debug(4, "Disregarding setting RTP on %s: channel is not bridged\n", ast_channel_name(chan));
456  SCOPE_EXIT_RTN_VALUE(0, "Channel not bridged\n");
457  }
458 
459  if (nat_active && session->endpoint->media.direct_media.disable_on_nat) {
460  ast_debug(4, "Disregarding setting RTP on %s: NAT is active\n", ast_channel_name(chan));
461  SCOPE_EXIT_RTN_VALUE(0, "NAT is active\n");
462  }
463 
465  if (!cdata) {
467  }
468 
470  ast_log(LOG_ERROR, "Unable to send direct media request for channel %s\n", ast_channel_name(chan));
471  ao2_ref(cdata, -1);
472  }
473 
475 }
static int send_direct_media_request(void *data)
Definition: chan_pjsip.c:388
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:369
static int cdata(void *userdata, int state, const char *cdata, size_t len)
struct ast_rtp_instance * vrtp
Definition: chan_pjsip.c:353
struct ast_channel * chan
Definition: chan_pjsip.c:351
struct ast_rtp_instance * rtp
Definition: chan_pjsip.c:352
struct ast_format_cap * cap
Definition: chan_pjsip.c:354

◆ 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 2152 of file chan_pjsip.c.

2153 {
2154  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2155  struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
2156 
2157  if (!trnf_data) {
2158  return -1;
2159  }
2160 
2161  if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
2162  ast_log(LOG_WARNING, "Error requesting transfer\n");
2163  ao2_cleanup(trnf_data);
2164  return -1;
2165  }
2166 
2167  return 0;
2168 }
static struct transfer_data * transfer_data_alloc(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1879
static int transfer(void *data)
Definition: chan_pjsip.c:2117

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

◆ chan_pjsip_write()

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

Definition at line 1032 of file chan_pjsip.c.

1033 {
1034  return chan_pjsip_write_stream(ast, -1, frame);
1035 }
static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f)
Definition: chan_pjsip.c:942

References chan_pjsip_write_stream().

◆ 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 942 of file chan_pjsip.c.

943 {
944  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
945  struct ast_sip_session *session = channel->session;
946  struct ast_sip_session_media *media = NULL;
947  int res = 0;
948 
949  /* The core provides a guarantee that the stream will exist when we are called if stream_num is provided */
950  if (stream_num >= 0) {
951  /* What is not guaranteed is that a media session will exist */
954  }
955  }
956 
957  switch (frame->frametype) {
958  case AST_FRAME_VOICE:
959  if (!media) {
960  return 0;
961  } else if (media->type != AST_MEDIA_TYPE_AUDIO) {
962  ast_debug(3, "Channel %s stream %d is of type '%s', not audio!\n",
964  return 0;
965  } else if (media == channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO] &&
968  struct ast_str *write_transpath = ast_str_alloca(256);
969  struct ast_str *read_transpath = ast_str_alloca(256);
970 
972  "Channel %s asked to send %s frame when native formats are %s (rd:%s->%s;%s wr:%s->%s;%s)\n",
973  ast_channel_name(ast),
974  ast_format_get_name(frame->subclass.format),
978  ast_translate_path_to_str(ast_channel_readtrans(ast), &read_transpath),
981  ast_translate_path_to_str(ast_channel_writetrans(ast), &write_transpath));
982  return 0;
983  } else if (media->write_callback) {
984  res = media->write_callback(session, media, frame);
985 
986  }
987  break;
988  case AST_FRAME_VIDEO:
989  if (!media) {
990  return 0;
991  } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
992  ast_debug(3, "Channel %s stream %d is of type '%s', not video!\n",
993  ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
994  return 0;
995  } else if (media->write_callback) {
996  res = media->write_callback(session, media, frame);
997  }
998  break;
999  case AST_FRAME_MODEM:
1000  if (!media) {
1001  return 0;
1002  } else if (media->type != AST_MEDIA_TYPE_IMAGE) {
1003  ast_debug(3, "Channel %s stream %d is of type '%s', not image!\n",
1004  ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1005  return 0;
1006  } else if (media->write_callback) {
1007  res = media->write_callback(session, media, frame);
1008  }
1009  break;
1010  case AST_FRAME_CNG:
1011  break;
1012  case AST_FRAME_RTCP:
1013  /* We only support writing out feedback */
1014  if (frame->subclass.integer != AST_RTP_RTCP_PSFB || !media) {
1015  return 0;
1016  } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
1017  ast_debug(3, "Channel %s stream %d is of type '%s', not video! Unable to write RTCP feedback.\n",
1018  ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1019  return 0;
1020  } else if (media->write_callback) {
1021  res = media->write_callback(session, media, frame);
1022  }
1023  break;
1024  default:
1025  ast_log(LOG_WARNING, "Can't send %u type frames with PJSIP\n", frame->frametype);
1026  break;
1027  }
1028 
1029  return res;
1030 }
struct ast_trans_pvt * ast_channel_readtrans(const struct ast_channel *chan)
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
struct ast_trans_pvt * ast_channel_writetrans(const struct ast_channel *chan)
@ AST_MEDIA_TYPE_IMAGE
Definition: codec.h:34
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
@ AST_FRAME_VIDEO
@ AST_FRAME_RTCP
@ AST_FRAME_MODEM
#define AST_RTP_RTCP_PSFB
Definition: rtp_engine.h:299
#define ast_str_alloca(init_len)
Definition: strings.h:826
ast_sip_session_media_write_cb write_callback
The write callback when writing frames.
int stream_num
The stream number to place into any resulting frames.
Support for dynamic strings.
Definition: strings.h:604
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:928

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::channel, 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, session, ast_sip_session_media_state::sessions, ast_sip_session_media::stream_num, ast_frame::subclass, ast_sip_session_media::type, and ast_sip_session_media::write_callback.

Referenced by chan_pjsip_write().

◆ 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 319 of file chan_pjsip.c.

321 {
322  int changed = 0, position = -1;
323 
324  if (media->rtp) {
325  position = rtp_find_rtcp_fd_position(session, media->rtp);
326  }
327 
328  if (rtp) {
330  if (media->rtp) {
331  if (position != -1) {
332  ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, -1);
333  }
335  }
336  } else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
338  changed = 1;
339  if (media->rtp) {
341  if (position != -1) {
342  ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, ast_rtp_instance_fd(media->rtp, 1));
343  }
344  }
345  }
346 
347  return changed;
348 }
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:298
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2425
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
#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:1228
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
@ AST_RTP_PROPERTY_RTCP
Definition: rtp_engine.h:123
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:2184
struct ast_sockaddr direct_media_addr
Direct media address.

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

Referenced by send_direct_media_request().

◆ 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 2497 of file chan_pjsip.c.

2498 {
2499  session->channel = NULL;
2502 }

References ast_channel_tech_pvt_set(), NULL, session, and set_channel_on_rtp_instance().

Referenced by chan_pjsip_hangup(), and hangup().

◆ 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 518 of file chan_pjsip.c.

519 {
520  struct ast_format_cap *cap_from_top;
521  int res;
522  SCOPE_ENTER(1, "Topology: %s Formats: %s\n",
525 
526  cap_from_top = ast_stream_topology_get_formats(top);
527 
528  if (!cap_from_top) {
529  SCOPE_EXIT_RTN_VALUE(0, "Topology had no formats\n");
530  }
531 
532  res = ast_format_cap_iscompatible(cap_from_top, cap);
533  ao2_ref(cap_from_top, -1);
534 
535  SCOPE_EXIT_RTN_VALUE(res, "Compatible? %s\n", res ? "yes" : "no");
536 }
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:653

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

◆ direct_media_mitigate_glare()

static int direct_media_mitigate_glare ( struct ast_sip_session session)
static

Definition at line 268 of file chan_pjsip.c.

269 {
270  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
271 
272  if (session->endpoint->media.direct_media.glare_mitigation ==
274  return 0;
275  }
276 
277  datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
278  if (!datastore) {
279  return 0;
280  }
281 
282  /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
283  ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
284 
285  if ((session->endpoint->media.direct_media.glare_mitigation ==
287  session->inv_session->role == PJSIP_ROLE_UAC) ||
288  (session->endpoint->media.direct_media.glare_mitigation ==
290  session->inv_session->role == PJSIP_ROLE_UAS)) {
291  return 1;
292  }
293 
294  return 0;
295 }
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING
Definition: res_pjsip.h:522
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING
Definition: res_pjsip.h:518
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.

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(), NULL, RAII_VAR, and session.

Referenced by send_direct_media_request().

◆ 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 1585 of file chan_pjsip.c.

1587 {
1589  int res;
1590  SCOPE_ENTER(1);
1591 
1593  if (!refresh_data) {
1594  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create refresh_data\n");
1595  }
1596 
1598  if (res) {
1600  }
1601  SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
1602 }
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:1517
static int send_topology_change_refresh(void *data)
Definition: chan_pjsip.c:1568
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
Definition: chan_pjsip.c:1509

References ast_sip_push_task(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, send_topology_change_refresh(), session, topology_change_refresh_data_alloc(), and topology_change_refresh_data_free().

Referenced by chan_pjsip_indicate().

◆ hangup()

static int hangup ( void *  data)
static

Definition at line 2504 of file chan_pjsip.c.

2505 {
2506  struct hangup_data *h_data = data;
2507  struct ast_channel *ast = h_data->chan;
2508  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2509  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2510 
2511  /*
2512  * Before cleaning we have to ensure that channel or its session is not NULL
2513  * we have seen rare case when taskprocessor calls hangup but channel is NULL
2514  * due to SIP session timeout and answer happening at the same time
2515  */
2516  if (channel) {
2517  struct ast_sip_session *session = channel->session;
2518  if (session) {
2519  int cause = h_data->cause;
2520 
2521  /*
2522  * It's possible that session_terminate might cause the session to be destroyed
2523  * immediately so we need to keep a reference to it so we can NULL session->channel
2524  * afterwards.
2525  */
2529  }
2531  }
2532  ao2_cleanup(h_data);
2534 }
struct ast_channel * chan
Definition: chan_pjsip.c:2472

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

Referenced by ast_hangup(), chan_pjsip_hangup(), destroy_conference_bridge(), hangup_data_destroy(), hangup_data_init(), hangup_playback(), manage_calls(), play_on_channel(), playback_final_update(), and sla_stop_ringing_station().

◆ hangup_cause2sip()

static int hangup_cause2sip ( int  cause)
static

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

Definition at line 2423 of file chan_pjsip.c.

2424 {
2425  switch (cause) {
2426  case AST_CAUSE_UNALLOCATED: /* 1 */
2427  case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
2428  case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
2429  return 404;
2430  case AST_CAUSE_CONGESTION: /* 34 */
2431  case AST_CAUSE_SWITCH_CONGESTION: /* 42 */
2432  return 503;
2433  case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
2434  return 408;
2435  case AST_CAUSE_NO_ANSWER: /* 19 */
2436  case AST_CAUSE_UNREGISTERED: /* 20 */
2437  return 480;
2438  case AST_CAUSE_CALL_REJECTED: /* 21 */
2439  return 403;
2440  case AST_CAUSE_NUMBER_CHANGED: /* 22 */
2441  return 410;
2442  case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */
2443  return 480;
2445  return 484;
2446  case AST_CAUSE_USER_BUSY:
2447  return 486;
2448  case AST_CAUSE_FAILURE:
2449  return 500;
2450  case AST_CAUSE_FACILITY_REJECTED: /* 29 */
2451  return 501;
2453  return 503;
2455  return 502;
2456  case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
2457  return 488;
2458  case AST_CAUSE_INTERWORKING: /* Unspecified Interworking issues */
2459  return 500;
2460  case AST_CAUSE_NOTDEFINED:
2461  default:
2462  ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
2463  return 0;
2464  }
2465 
2466  /* Never reached */
2467  return 0;
2468 }
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:123
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:98
#define AST_CAUSE_INTERWORKING
Definition: causes.h:146
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:112
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:130
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:116
#define AST_CAUSE_CHAN_NOT_IMPLEMENTED
Definition: causes.h:132
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:115
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:108
#define AST_CAUSE_NOTDEFINED
Definition: causes.h:155
#define AST_CAUSE_FACILITY_REJECTED
Definition: causes.h:117
#define AST_CAUSE_NORMAL_UNSPECIFIED
Definition: causes.h:119
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
Definition: causes.h:99
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:100
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:154
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:109
#define AST_CAUSE_USER_BUSY
Definition: causes.h:107

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

◆ hangup_data_alloc()

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

Definition at line 2482 of file chan_pjsip.c.

2483 {
2484  struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
2485 
2486  if (!h_data) {
2487  return NULL;
2488  }
2489 
2490  h_data->cause = cause;
2491  h_data->chan = ast_channel_ref(chan);
2492 
2493  return h_data;
2494 }
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void hangup_data_destroy(void *obj)
Definition: chan_pjsip.c:2475

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

Referenced by chan_pjsip_hangup().

◆ hangup_data_destroy()

static void hangup_data_destroy ( void *  obj)
static

Definition at line 2475 of file chan_pjsip.c.

2476 {
2477  struct hangup_data *h_data = obj;
2478 
2479  h_data->chan = ast_channel_unref(h_data->chan);
2480 }

References ast_channel_unref, and hangup_data::chan.

Referenced by hangup_data_alloc().

◆ hangup_sip2cause()

static int hangup_sip2cause ( int  cause)
static

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 2881 of file chan_pjsip.c.

2882 {
2883  /* Possible values taken from causes.h */
2884 
2885  switch(cause) {
2886  case 401: /* Unauthorized */
2887  return AST_CAUSE_CALL_REJECTED;
2888  case 403: /* Not found */
2889  return AST_CAUSE_CALL_REJECTED;
2890  case 404: /* Not found */
2891  return AST_CAUSE_UNALLOCATED;
2892  case 405: /* Method not allowed */
2893  return AST_CAUSE_INTERWORKING;
2894  case 407: /* Proxy authentication required */
2895  return AST_CAUSE_CALL_REJECTED;
2896  case 408: /* No reaction */
2898  case 409: /* Conflict */
2900  case 410: /* Gone */
2901  return AST_CAUSE_NUMBER_CHANGED;
2902  case 411: /* Length required */
2903  return AST_CAUSE_INTERWORKING;
2904  case 413: /* Request entity too large */
2905  return AST_CAUSE_INTERWORKING;
2906  case 414: /* Request URI too large */
2907  return AST_CAUSE_INTERWORKING;
2908  case 415: /* Unsupported media type */
2909  return AST_CAUSE_INTERWORKING;
2910  case 420: /* Bad extension */
2912  case 480: /* No answer */
2913  return AST_CAUSE_NO_ANSWER;
2914  case 481: /* No answer */
2915  return AST_CAUSE_INTERWORKING;
2916  case 482: /* Loop detected */
2917  return AST_CAUSE_INTERWORKING;
2918  case 483: /* Too many hops */
2919  return AST_CAUSE_NO_ANSWER;
2920  case 484: /* Address incomplete */
2922  case 485: /* Ambiguous */
2923  return AST_CAUSE_UNALLOCATED;
2924  case 486: /* Busy everywhere */
2925  return AST_CAUSE_BUSY;
2926  case 487: /* Request terminated */
2927  return AST_CAUSE_INTERWORKING;
2928  case 488: /* No codecs approved */
2930  case 491: /* Request pending */
2931  return AST_CAUSE_INTERWORKING;
2932  case 493: /* Undecipherable */
2933  return AST_CAUSE_INTERWORKING;
2934  case 500: /* Server internal failure */
2935  return AST_CAUSE_FAILURE;
2936  case 501: /* Call rejected */
2938  case 502:
2940  case 503: /* Service unavailable */
2941  return AST_CAUSE_CONGESTION;
2942  case 504: /* Gateway timeout */
2944  case 505: /* SIP version not supported */
2945  return AST_CAUSE_INTERWORKING;
2946  case 600: /* Busy everywhere */
2947  return AST_CAUSE_USER_BUSY;
2948  case 603: /* Decline */
2949  return AST_CAUSE_CALL_REJECTED;
2950  case 604: /* Does not exist anywhere */
2951  return AST_CAUSE_UNALLOCATED;
2952  case 606: /* Not acceptable */
2954  default:
2955  if (cause < 500 && cause >= 400) {
2956  /* 4xx class error that is unknown - someting wrong with our request */
2957  return AST_CAUSE_INTERWORKING;
2958  } else if (cause < 600 && cause >= 500) {
2959  /* 5xx class error - problem in the remote end */
2960  return AST_CAUSE_CONGESTION;
2961  } else if (cause < 700 && cause >= 600) {
2962  /* 6xx - global errors in the 4xx class */
2963  return AST_CAUSE_INTERWORKING;
2964  }
2965  return AST_CAUSE_NORMAL;
2966  }
2967  /* Never reached */
2968  return 0;
2969 }
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:122
#define AST_CAUSE_NORMAL
Definition: causes.h:151
#define AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE
Definition: causes.h:143
#define AST_CAUSE_BUSY
Definition: causes.h:149

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_update_cause(), and chan_pjsip_session_end().

◆ indicate()

static int indicate ( void *  data)
static

Definition at line 1326 of file chan_pjsip.c.

1327 {
1328  pjsip_tx_data *packet = NULL;
1329  struct indicate_data *ind_data = data;
1330  struct ast_sip_session *session = ind_data->session;
1331  int response_code = ind_data->response_code;
1332 
1333  if ((session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
1334  (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
1336  }
1337 
1338  ao2_ref(ind_data, -1);
1339 
1340  return 0;
1341 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1286

References ao2_ref, ast_sip_session_send_response(), NULL, indicate_data::response_code, indicate_data::session, and session.

Referenced by ast_channel_request_stream_topology_change(), ast_channel_stream_topology_changed(), chan_pjsip_indicate(), and indicate_data_internal().

◆ indicate_data_alloc()

static struct indicate_data* indicate_data_alloc ( struct ast_sip_session session,
int  condition,
int  response_code,
const void *  frame_data,
size_t  datalen 
)
static

Definition at line 1301 of file chan_pjsip.c.

1303 {
1304  struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
1305 
1306  if (!ind_data) {
1307  return NULL;
1308  }
1309 
1310  ind_data->frame_data = ast_malloc(datalen);
1311  if (!ind_data->frame_data) {
1312  ao2_ref(ind_data, -1);
1313  return NULL;
1314  }
1315 
1316  memcpy(ind_data->frame_data, frame_data, datalen);
1317  ind_data->datalen = datalen;
1318  ind_data->condition = condition;
1319  ind_data->response_code = response_code;
1320  ao2_ref(session, +1);
1321  ind_data->session = session;
1322 
1323  return ind_data;
1324 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
static void indicate_data_destroy(void *obj)
Definition: chan_pjsip.c:1293
void * frame_data
Definition: chan_pjsip.c:1289

References ao2_alloc, ao2_ref, ast_malloc, indicate_data::condition, indicate_data::datalen, indicate_data::frame_data, indicate_data_destroy(), NULL, indicate_data::response_code, indicate_data::session, and session.

Referenced by chan_pjsip_indicate().

◆ indicate_data_destroy()

static void indicate_data_destroy ( void *  obj)
static

Definition at line 1293 of file chan_pjsip.c.

1294 {
1295  struct indicate_data *ind_data = obj;
1296 
1297  ast_free(ind_data->frame_data);
1298  ao2_ref(ind_data->session, -1);
1299 }

References ao2_ref, ast_free, indicate_data::frame_data, and indicate_data::session.

Referenced by indicate_data_alloc().

◆ info_dtmf_data_alloc()

static struct info_dtmf_data * info_dtmf_data_alloc ( struct ast_sip_session session,
char  digit,
unsigned int  duration 
)
static

Definition at line 2226 of file chan_pjsip.c.

2227 {
2228  struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
2229  if (!dtmf_data) {
2230  return NULL;
2231  }
2232  ao2_ref(session, +1);
2233  dtmf_data->session = session;
2234  dtmf_data->digit = digit;
2235  dtmf_data->duration = duration;
2236  return dtmf_data;
2237 }
static void info_dtmf_data_destroy(void *obj)
Definition: chan_pjsip.c:2220
struct ast_sip_session * session
Definition: chan_pjsip.c:2215

References ao2_alloc, ao2_ref, digit, info_dtmf_data::digit, info_dtmf_data::duration, info_dtmf_data_destroy(), NULL, info_dtmf_data::session, and session.

Referenced by chan_pjsip_digit_end(), and chan_pjsip_indicate().

◆ info_dtmf_data_destroy()

static void info_dtmf_data_destroy ( void *  obj)
static

Definition at line 2220 of file chan_pjsip.c.

2221 {
2222  struct info_dtmf_data *dtmf_data = obj;
2223  ao2_ref(dtmf_data->session, -1);
2224 }

References ao2_ref, and info_dtmf_data::session.

Referenced by info_dtmf_data_alloc().

◆ is_colp_update_allowed()

static int is_colp_update_allowed ( struct ast_sip_session session)
static

Definition at line 1395 of file chan_pjsip.c.

1396 {
1397  struct ast_party_id connected_id;
1398  int update_allowed = 0;
1399 
1400  if (!session->endpoint->id.send_connected_line
1401  || (!session->endpoint->id.send_pai && !session->endpoint->id.send_rpid)) {
1402  return 0;
1403  }
1404 
1405  /*
1406  * Check if privacy allows the update. Check while the channel
1407  * is locked so we can work with the shallow connected_id copy.
1408  */
1409  ast_channel_lock(session->channel);
1410  connected_id = ast_channel_connected_effective_id(session->channel);
1411  if (connected_id.number.valid
1412  && (session->endpoint->id.trust_outbound
1414  update_allowed = 1;
1415  }
1416  ast_channel_unlock(session->channel);
1417 
1418  return update_allowed;
1419 }
#define AST_PRES_ALLOWED
Definition: callerid.h:324
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1815
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
Information needed to identify an endpoint in a call.
Definition: channel.h:338

References ast_channel_connected_effective_id(), ast_channel_lock, ast_channel_unlock, ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_party_id::number, session, and ast_party_number::valid.

Referenced by update_connected_line_information().

◆ is_compatible_format()

static int is_compatible_format ( struct ast_sip_session session,
struct ast_frame f 
)
static

Determine if the given frame is in a format we've negotiated.

Definition at line 817 of file chan_pjsip.c.

818 {
819  struct ast_stream_topology *topology = session->active_media_state->topology;
820  struct ast_stream *stream = ast_stream_topology_get_stream(topology, f->stream_num);
821  const struct ast_format_cap *cap = ast_stream_get_formats(stream);
822 
824 }
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330

References ast_format_cap_iscompatible_format(), AST_FORMAT_CMP_NOT_EQUAL, ast_stream_get_formats(), ast_stream_topology_get_stream(), ast_frame_subclass::format, session, ast_frame::stream_num, and ast_frame::subclass.

Referenced by chan_pjsip_read_stream().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 3325 of file chan_pjsip.c.

3326 {
3327  struct ao2_container *endpoints;
3328 
3330  return AST_MODULE_LOAD_DECLINE;
3331  }
3332 
3334 
3336 
3338  ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
3339  goto end;
3340  }
3341 
3343  ast_log(LOG_ERROR, "Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
3344  goto end;
3345  }
3346 
3348  ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI dialplan function\n");
3349  goto end;
3350  }
3351 
3353  ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
3354  goto end;
3355  }
3356 
3358  ast_log(LOG_WARNING, "Unable to register PJSIP_DTMF_MODE dialplan function\n");
3359  goto end;
3360  }
3361 
3363  ast_log(LOG_WARNING, "Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
3364  goto end;
3365  }
3366 
3368  ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
3369  goto end;
3370  }
3371 
3373 
3376 
3379  uid_hold_sort_fn, NULL))) {
3380  ast_log(LOG_ERROR, "Unable to create held channels container\n");
3381  goto end;
3382  }
3383 
3387 
3389  ast_log(LOG_ERROR, "Unable to register PJSIP Channel CLI\n");
3390  goto end;
3391  }
3392 
3393  /* since endpoints are loaded before the channel driver their device
3394  states get set to 'invalid', so they need to be updated */
3395  if ((endpoints = ast_sip_get_endpoints())) {
3397  ao2_ref(endpoints, -1);
3398  }
3399 
3400  return 0;
3401 
3402 end:
3419 
3420  return AST_MODULE_LOAD_DECLINE;
3421 }
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition: astobj2.h:365
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
Definition: astobj2.h:1188
static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
Definition: chan_pjsip.c:1077
static int update_devstate(void *obj, void *arg, int flags)
Definition: chan_pjsip.c:3275
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
Definition: chan_pjsip.c:143
static struct ast_custom_function chan_pjsip_dial_contacts_function
Definition: chan_pjsip.c:3282
static int uid_hold_hash_fn(const void *obj, const int flags)
Definition: chan_pjsip.c:1059
static struct ast_sip_session_supplement pbx_start_supplement
Definition: chan_pjsip.c:3170
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
Definition: chan_pjsip.c:478
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1936
static const char channel_type[]
Definition: chan_pjsip.c:78
static struct ast_custom_function moh_passthrough_function
Definition: chan_pjsip.c:3304
static struct ast_custom_function media_offer_function
Definition: chan_pjsip.c:3292
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
Definition: chan_pjsip.c:164
static struct ast_custom_function chan_pjsip_parse_uri_function
Definition: chan_pjsip.c:3287
static struct ast_custom_function session_refresh_function
Definition: chan_pjsip.c:3310
static struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Definition: chan_pjsip.c:155
static struct ast_sip_session_supplement call_pickup_supplement
Definition: chan_pjsip.c:3130
static struct ast_custom_function dtmf_mode_function
Definition: chan_pjsip.c:3298
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
Definition: cli_commands.c:448
char * end
Definition: eagi_proxy.c:73
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
static struct ao2_container * endpoints
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1543
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:126
struct ao2_container * ast_sip_get_endpoints(void)
Retrieve any endpoints available to sorcery.
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:110
#define ast_sip_session_register_supplement(supplement)
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
Definition: pjsip_session.c:63
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:847
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
Generic container type.
struct ast_format_cap * capabilities
Definition: channel.h:632

References AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_callback, ao2_cleanup, ao2_container_alloc_hash, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_ref, ast_channel_register(), ast_channel_unregister(), ast_custom_function_register, ast_custom_function_unregister(), ast_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MODULE_LOAD_DECLINE, ast_rtp_glue_register, ast_rtp_glue_unregister(), ast_sip_get_endpoints(), ast_sip_register_service(), ast_sip_session_register_supplement, ast_sip_session_unregister_supplement(), ast_sip_unregister_service(), call_pickup_supplement, ast_channel_tech::capabilities, chan_pjsip_ack_supplement, chan_pjsip_dial_contacts_function, chan_pjsip_parse_uri_function, chan_pjsip_rtp_glue, chan_pjsip_supplement, chan_pjsip_supplement_response, chan_pjsip_tech, channel_type, dtmf_mode_function, end, endpoints, LOG_ERROR, LOG_WARNING, media_offer_function, moh_passthrough_function, NULL, OBJ_NODATA, pbx_start_supplement, pjsip_channel_cli_register(), pjsip_uids_onhold, refer_callback_module, session_refresh_function, uid_hold_hash_fn(), uid_hold_sort_fn(), and update_devstate().

◆ local_hold_set_state()

static void local_hold_set_state ( struct ast_sip_session_media session_media,
unsigned int  held 
)
static

Callback which changes the value of locally held on the media stream.

Definition at line 1475 of file chan_pjsip.c.

1476 {
1477  if (session_media) {
1478  session_media->locally_held = held;
1479  }
1480 }
unsigned int locally_held
Stream is on hold by local side.

References ast_sip_session_media::locally_held.

Referenced by remote_send_hold_refresh().

◆ on_topology_change_response()

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

Definition at line 1542 of file chan_pjsip.c.

1543 {
1544  SCOPE_ENTER(3, "%s: Received response code %d. PT: %s AT: %s\n", ast_sip_session_get_name(session),
1545  rdata->msg_info.msg->line.status.code,
1546  ast_str_tmp(256, ast_stream_topology_to_str(session->pending_media_state->topology, &STR_TMP)),
1547  ast_str_tmp(256, ast_stream_topology_to_str(session->active_media_state->topology, &STR_TMP)));
1548 
1549 
1550  if (PJSIP_IS_STATUS_IN_CLASS(rdata->msg_info.msg->line.status.code, 200)) {
1551  /* The topology was changed to something new so give notice to what requested
1552  * it so it queries the channel and updates accordingly.
1553  */
1554  if (session->channel) {
1556  SCOPE_EXIT_RTN_VALUE(0, "%s: Queued topology change frame\n", ast_sip_session_get_name(session));
1557  }
1558  SCOPE_EXIT_RTN_VALUE(0, "%s: No channel? Can't queue topology change frame\n", ast_sip_session_get_name(session));
1559  } else if (300 <= rdata->msg_info.msg->line.status.code) {
1560  /* The topology change failed, so drop the current pending media state */
1561  ast_sip_session_media_state_reset(session->pending_media_state);
1562  SCOPE_EXIT_RTN_VALUE(0, "%s: response code > 300. Resetting pending media state\n", ast_sip_session_get_name(session));
1563  }
1564 
1565  SCOPE_EXIT_RTN_VALUE(0, "%s: Nothing to do\n", ast_sip_session_get_name(session));
1566 }
void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state)
Reset a media state to a clean state.

References AST_CONTROL_STREAM_TOPOLOGY_CHANGED, ast_queue_control(), ast_sip_session_get_name(), ast_sip_session_media_state_reset(), ast_str_tmp, ast_stream_topology_to_str(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and session.

Referenced by send_topology_change_refresh().

◆ pbx_start_incoming_request()

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

Definition at line 3136 of file chan_pjsip.c.

3137 {
3138  int res;
3140 
3141  /* Check for a to-tag to determine if this is a reinvite */
3142  if (rdata->msg_info.to->tag.slen) {
3143  /* We don't care about reinvites */
3144  SCOPE_EXIT_RTN_VALUE(0, "Reinvite\n");
3145  }
3146 
3147  res = ast_pbx_start(session->channel);
3148 
3149  switch (res) {
3150  case AST_PBX_FAILED:
3151  ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
3153  ast_hangup(session->channel);
3154  break;
3155  case AST_PBX_CALL_LIMIT:
3156  ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
3158  ast_hangup(session->channel);
3159  break;
3160  case AST_PBX_SUCCESS:
3161  default:
3162  break;
3163  }
3164 
3165  ast_debug(3, "Started PBX on new PJSIP channel %s\n", ast_channel_name(session->channel));
3166 
3167  SCOPE_EXIT_RTN_VALUE((res == AST_PBX_SUCCESS) ? 0 : -1, "RC: %d\n", res);
3168 }
@ AST_PBX_FAILED
Definition: pbx.h:355
@ AST_PBX_CALL_LIMIT
Definition: pbx.h:356
@ AST_PBX_SUCCESS
Definition: pbx.h:354
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4715

References AST_CAUSE_SWITCH_CONGESTION, ast_channel_hangupcause_set(), ast_channel_name(), ast_debug, ast_hangup(), ast_log, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_sip_session_get_name(), LOG_WARNING, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and session.

◆ remote_send_hold()

static int remote_send_hold ( void *  data)
static

Update local hold state to be held.

Definition at line 1493 of file chan_pjsip.c.

1494 {
1495  return remote_send_hold_refresh(data, 1);
1496 }
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.
Definition: chan_pjsip.c:1483

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

◆ remote_send_hold_refresh()

static int remote_send_hold_refresh ( struct ast_sip_session session,
unsigned int  held 
)
static

Update local hold state and send a re-INVITE with the new SDP.

Definition at line 1483 of file chan_pjsip.c.

1484 {
1485  AST_VECTOR_CALLBACK_VOID(&session->active_media_state->sessions, local_hold_set_state, held);
1487  ao2_ref(session, -1);
1488 
1489  return 0;
1490 }
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.
Definition: chan_pjsip.c:1475
@ AST_SIP_SESSION_REFRESH_METHOD_INVITE
Definition: res_pjsip.h:507
int ast_sip_session_refresh(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *media_state)
Send a reinvite or UPDATE on a session.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:862

References ao2_ref, ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, AST_VECTOR_CALLBACK_VOID, local_hold_set_state(), NULL, and session.

Referenced by remote_send_hold(), and remote_send_unhold().

◆ remote_send_unhold()

static int remote_send_unhold ( void *  data)
static

Update local hold state to be unheld.

Definition at line 1499 of file chan_pjsip.c.

1500 {
1501  return remote_send_hold_refresh(data, 0);
1502 }

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

◆ request()

static int request ( void *  obj)
static

Definition at line 2580 of file chan_pjsip.c.

2581 {
2582  struct request_data *req_data = obj;
2583  struct ast_sip_session *session = NULL;
2584  char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
2585  struct ast_sip_endpoint *endpoint;
2586 
2588  AST_APP_ARG(endpoint);
2589  AST_APP_ARG(aor);
2590  );
2591  SCOPE_ENTER(1, "%s\n",tmp);
2592 
2593  if (ast_strlen_zero(tmp)) {
2594  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty destination\n");
2596  SCOPE_EXIT_RTN_VALUE(-1, "Empty destination\n");
2597  }
2598 
2600 
2602  /* If a request user has been specified extract it from the endpoint name portion */
2603  if ((endpoint_name = strchr(args.endpoint, '@'))) {
2604  request_user = args.endpoint;
2605  *endpoint_name++ = '\0';
2606  } else {
2607  endpoint_name = args.endpoint;
2608  }
2609 
2610  if (ast_strlen_zero(endpoint_name)) {
2611  if (request_user) {
2612  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2613  request_user);
2614  } else {
2615  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2616  }
2618  SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2619  }
2620  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2621  endpoint_name);
2622  if (!endpoint) {
2623  ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2625  SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2626  }
2627  } else {
2628  /* First try to find an exact endpoint match, for single (user) or multi-domain (user@domain) */
2629  endpoint_name = args.endpoint;
2630  if (ast_strlen_zero(endpoint_name)) {
2631  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2633  SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2634  }
2635  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2636  endpoint_name);
2637  if (!endpoint) {
2638  /* It seems it's not a multi-domain endpoint or single endpoint exact match,
2639  * it's possible that it's a SIP trunk with a specified user (user@trunkname),
2640  * so extract the user before @ sign.
2641  */
2642  endpoint_name = strchr(args.endpoint, '@');
2643  if (!endpoint_name) {
2644  /*
2645  * Couldn't find an '@' so it had to be an endpoint
2646  * name that doesn't exist.
2647  */
2648  ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n",
2649  args.endpoint);
2651  SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2652  }
2653  request_user = args.endpoint;
2654  *endpoint_name++ = '\0';
2655 
2656  if (ast_strlen_zero(endpoint_name)) {
2657  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2658  request_user);
2660  SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2661  }
2662 
2663  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2664  endpoint_name);
2665  if (!endpoint) {
2666  ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2668  SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2669  }
2670  }
2671  }
2672 
2673  session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user,
2674  req_data->topology);
2675  ao2_ref(endpoint, -1);
2676  if (!session) {
2677  ast_log(LOG_ERROR, "Failed to create outgoing session to endpoint '%s'\n", endpoint_name);
2679  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create session\n");
2680  }
2681 
2682  req_data->session = session;
2683 
2685 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static int tmp()
Definition: bt_open.c:389
#define AST_CAUSE_CHANNEL_UNACCEPTABLE
Definition: causes.h:102
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
unsigned int ast_sip_get_disable_multi_domain(void)
Retrieve the system setting 'disable multi domain'.
struct ast_sip_session * ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, const char *location, const char *request_user, struct ast_stream_topology *req_topology)
Create a new outgoing SIP session.
struct ast_sip_session * session
Definition: chan_pjsip.c:2574
const char * dest
Definition: chan_pjsip.c:2576
const char * args

References ao2_ref, args, AST_APP_ARG, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_NO_ROUTE_DESTINATION, AST_DECLARE_APP_ARGS, ast_log, AST_NONSTANDARD_APP_ARGS, ast_sip_get_disable_multi_domain(), ast_sip_get_sorcery(), ast_sip_session_create_outgoing(), ast_sorcery_retrieve_by_id(), ast_strdupa, ast_strlen_zero(), request_data::cause, request_data::dest, LOG_ERROR, NULL, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, request_data::session, session, tmp(), and request_data::topology.

Referenced by ast_bridge_channel_merge_inhibit(), ast_bridge_merge_inhibit(), ast_http_body_discard(), ast_http_body_read_status(), ast_http_get_contents(), ast_http_request_close_on_completion(), ast_http_send(), ast_parse_digest(), AST_TEST_DEFINE(), bridge_manager_destroy(), bridge_manager_service_req(), bridge_manager_thread(), bridge_merge_inhibit_nolock(), chan_pjsip_request_with_stream_topology(), ewscal_write_event(), get_ewscal_ids_for(), http_request_tracking_init(), http_request_tracking_setup(), httpd_process_request(), parse_ewscal_id(), send_ews_request_and_parse(), setup_env(), xmpp_pubsub_build_node_request(), xmpp_pubsub_build_publish_skeleton(), xmpp_pubsub_delete_node(), xmpp_pubsub_handle_error(), xmpp_pubsub_iq_create(), xmpp_pubsub_publish_device_state(), xmpp_pubsub_publish_mwi(), xmpp_pubsub_purge_nodes(), xmpp_pubsub_request_nodes(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

◆ rtp_direct_media_data_create()

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 
)
static

Definition at line 369 of file chan_pjsip.c.

372 {
374 
375  if (!cdata) {
376  return NULL;
377  }
378 
379  cdata->chan = ao2_bump(chan);
380  cdata->rtp = ao2_bump(rtp);
381  cdata->vrtp = ao2_bump(vrtp);
382  cdata->cap = ao2_bump((struct ast_format_cap *)cap);
383  cdata->session = ao2_bump(session);
384 
385  return cdata;
386 }
static void rtp_direct_media_data_destroy(void *data)
Definition: chan_pjsip.c:358

References ao2_alloc, ao2_bump, rtp_direct_media_data::cap, cdata(), rtp_direct_media_data::chan, NULL, rtp_direct_media_data::rtp, rtp_direct_media_data_destroy(), session, and rtp_direct_media_data::vrtp.

◆ rtp_direct_media_data_destroy()

static void rtp_direct_media_data_destroy ( void *  data)
static

Definition at line 358 of file chan_pjsip.c.

359 {
360  struct rtp_direct_media_data *cdata = data;
361 
362  ao2_cleanup(cdata->session);
363  ao2_cleanup(cdata->cap);
364  ao2_cleanup(cdata->vrtp);
365  ao2_cleanup(cdata->rtp);
366  ao2_cleanup(cdata->chan);
367 }

References ao2_cleanup, and cdata().

Referenced by rtp_direct_media_data_create().

◆ rtp_find_rtcp_fd_position()

static int rtp_find_rtcp_fd_position ( struct ast_sip_session session,
struct ast_rtp_instance rtp 
)
static

Helper function to find the position for RTCP.

Definition at line 298 of file chan_pjsip.c.

299 {
300  int index;
301 
302  for (index = 0; index < AST_VECTOR_SIZE(&session->active_media_state->read_callbacks); ++index) {
303  struct ast_sip_session_media_read_callback_state *callback_state =
304  AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, index);
305 
306  if (callback_state->fd != ast_rtp_instance_fd(rtp, 1)) {
307  continue;
308  }
309 
310  return index;
311  }
312 
313  return -1;
314 }

References ast_rtp_instance_fd(), AST_VECTOR_GET_ADDR, AST_VECTOR_SIZE, ast_sip_session_media_read_callback_state::fd, and session.

Referenced by check_for_rtp_changes().

◆ send_direct_media_request()

static int send_direct_media_request ( void *  data)
static

Definition at line 388 of file chan_pjsip.c.

389 {
390  struct rtp_direct_media_data *cdata = data;
391  struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(cdata->chan);
392  struct ast_sip_session *session;
393  int changed = 0;
394  int res = 0;
395 
396  /* XXX In an ideal world each media stream would be direct, but for now preserve behavior
397  * and connect only the default media sessions for audio and video.
398  */
399 
400  /* The channel needs to be locked when checking for RTP changes.
401  * Otherwise, we could end up destroying an underlying RTCP structure
402  * at the same time that the channel thread is attempting to read RTCP
403  */
404  ast_channel_lock(cdata->chan);
405  session = channel->session;
406  if (session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
407  changed |= check_for_rtp_changes(
408  cdata->chan, cdata->rtp, session->active_media_state-