Asterisk - The Open Source Telephony Project  18.5.0
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)
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "res_pjsip,res_pjsip_session,res_pjsip_pubsub", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_session_supplement call_pickup_supplement
 
static unsigned int chan_idx
 
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
 
static struct ast_custom_function chan_pjsip_dial_contacts_function
 
static struct ast_custom_function chan_pjsip_parse_uri_function
 
static struct ast_rtp_glue chan_pjsip_rtp_glue
 Local glue for interacting with the RTP engine core. More...
 
static struct ast_sip_session_supplement chan_pjsip_supplement
 SIP session supplement structure. More...
 
static struct ast_sip_session_supplement chan_pjsip_supplement_response
 SIP session supplement structure just for responses. More...
 
struct ast_channel_tech chan_pjsip_tech
 PBX interface structure for channel registration. More...
 
static const char channel_type [] = "PJSIP"
 
static struct ast_datastore_info direct_media_mitigation_info = { }
 
static struct ast_custom_function dtmf_mode_function
 
static struct ast_custom_function media_offer_function
 
static struct ast_custom_function moh_passthrough_function
 
static struct ast_sip_session_supplement pbx_start_supplement
 
static struct ao2_containerpjsip_uids_onhold
 
static pjsip_module refer_callback_module
 REFER Callback module, used to attach session data structure to subscription. More...
 
static struct ast_custom_function session_refresh_function
 
static struct ast_datastore_info transport_info
 Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel. More...
 
static struct ast_threadstorage uniqueid_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_uniqueid_threadbuf , .custom_init = NULL , }
 

Detailed Description

PSJIP SIP Channel Driver.

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

Definition in file chan_pjsip.c.

Macro Definition Documentation

◆ UNIQUEID_BUFSIZE

#define UNIQUEID_BUFSIZE   256

Definition at line 76 of file chan_pjsip.c.

Referenced by chan_pjsip_get_uniqueid().

Function Documentation

◆ __init_uniqueid_threadbuf()

static void __init_uniqueid_threadbuf ( void  )
static

Definition at line 75 of file chan_pjsip.c.

83 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3438 of file chan_pjsip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3438 of file chan_pjsip.c.

◆ answer()

static int answer ( void *  data)
static

Definition at line 682 of file chan_pjsip.c.

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

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

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

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3438 of file chan_pjsip.c.

◆ call()

static int call ( void *  data)
static

Definition at line 2358 of file chan_pjsip.c.

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

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

2359 {
2360  struct ast_sip_channel_pvt *channel = data;
2361  struct ast_sip_session *session = channel->session;
2362  pjsip_tx_data *tdata;
2363  int res = 0;
2364  SCOPE_ENTER(1, "%s Topology: %s\n",
2365  ast_sip_session_get_name(session),
2367  );
2368 
2369 
2370  res = ast_sip_session_create_invite(session, &tdata);
2371 
2372  if (res) {
2373  ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2374  ast_queue_hangup(session->channel);
2375  } else {
2378  ast_sip_session_send_request(session, tdata);
2379  }
2380  ao2_ref(channel, -1);
2381  SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
2382 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
struct ast_sip_session_media_state * pending_media_state
int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
Creates an INVITE request.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
A structure describing a SIP session.
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:494
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
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2504
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
struct ast_stream_topology * topology
The media stream topology.
const char * ast_channel_name(const struct ast_channel *chan)
static void update_initial_connected_line(struct ast_sip_session *session)
Definition: chan_pjsip.c:2333

◆ call_pickup_incoming_request()

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

Definition at line 3065 of file chan_pjsip.c.

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

3066 {
3067  struct ast_features_pickup_config *pickup_cfg;
3068  struct ast_channel *chan;
3069 
3070  /* Check for a to-tag to determine if this is a reinvite */
3071  if (rdata->msg_info.to->tag.slen) {
3072  /* We don't care about reinvites */
3073  return 0;
3074  }
3075 
3076  pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
3077  if (!pickup_cfg) {
3078  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
3079  return 0;
3080  }
3081 
3082  if (strcmp(session->exten, pickup_cfg->pickupexten)) {
3083  ao2_ref(pickup_cfg, -1);
3084  return 0;
3085  }
3086  ao2_ref(pickup_cfg, -1);
3087 
3088  /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
3089  * changing the channel pointer in session to a different channel. To ensure we work on the right channel
3090  * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
3091  */
3092  chan = ast_channel_ref(session->channel);
3093  if (ast_pickup_call(chan)) {
3095  } else {
3097  }
3098  /* A hangup always occurs because the pickup operation will have either failed resulting in the call
3099  * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
3100  * the channel that was replaced, which should be hung up since it is literally in limbo not connected
3101  * to anything at all.
3102  */
3103  ast_hangup(chan);
3104  ast_channel_unref(chan);
3105 
3106  return 1;
3107 }
Main Channel structure associated with a channel.
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
char exten[AST_MAX_EXTENSION]
#define ast_log
Definition: astobj2.c:42
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
#define LOG_ERROR
Definition: logger.h:285
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:200
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
Configuration relating to call pickup.

◆ chan_pjsip_add_hold()

static int chan_pjsip_add_hold ( const char *  chan_uid)
static

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

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

Definition at line 1117 of file chan_pjsip.c.

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

Referenced by chan_pjsip_indicate().

1118 {
1119  RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1120 
1121  hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1122  if (hold_uid) {
1123  /* Device is already on hold. Nothing to do. */
1124  return 0;
1125  }
1126 
1127  /* Device wasn't in hold list already. Create a new one. */
1128  hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
1130  if (!hold_uid) {
1131  return -1;
1132  }
1133 
1134  ast_copy_string(hold_uid, chan_uid, strlen(chan_uid) + 1);
1135 
1136  if (ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
1137  return -1;
1138  }
1139 
1140  return 0;
1141 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1107
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ chan_pjsip_answer()

static int chan_pjsip_answer ( struct ast_channel ast)
static

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

Definition at line 726 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

727 {
729  struct ast_sip_session *session;
730  struct answer_data ans_data = { 0, };
731  int res;
732  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
733 
734  if (ast_channel_state(ast) == AST_STATE_UP) {
735  SCOPE_EXIT_RTN_VALUE(0, "Already up\n");
736  return 0;
737  }
738 
740  session = ao2_bump(channel->session);
741 
742  /* the answer task needs to be pushed synchronously otherwise a race condition
743  can occur between this thread and bridging (specifically when native bridging
744  attempts to do direct media) */
745  ast_channel_unlock(ast);
746  ans_data.session = session;
747  ans_data.indent = ast_trace_get_indent();
748  res = ast_sip_push_task_wait_serializer(session->serializer, answer, &ans_data);
749  if (res) {
750  if (res == -1) {
751  ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
752  ast_channel_name(session->channel));
753  }
754  ao2_ref(session, -1);
755  ast_channel_lock(ast);
756  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
757  }
758  ao2_ref(session, -1);
759  ast_channel_lock(ast);
760 
762 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define ast_trace_get_indent()
Definition: logger.h:704
A structure describing a SIP session.
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
unsigned long indent
Definition: chan_pjsip.c:679
static struct ast_mansession session
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
Definition: res_pjsip.c:5218
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
static int answer(void *data)
Definition: chan_pjsip.c:682
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
const char * ast_channel_name(const struct ast_channel *chan)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
struct ast_sip_session * session
Definition: chan_pjsip.c:678

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

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

Referenced by chan_pjsip_pvt_dtor().

2386 {
2388  SCOPE_ENTER(1, "%s Topology: %s\n", ast_sip_session_get_name(channel->session),
2390 
2391  ao2_ref(channel, +1);
2392  if (ast_sip_push_task(channel->session->serializer, call, channel)) {
2393  ast_log(LOG_WARNING, "Error attempting to place outbound call to '%s'\n", dest);
2394  ao2_cleanup(channel);
2395  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
2396  }
2397 
2398  SCOPE_EXIT_RTN_VALUE(0, "'call' task pushed\n");
2399 }
struct ast_sip_session_media_state * pending_media_state
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
static int call(void *data)
Definition: chan_pjsip.c:2358
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_log
Definition: astobj2.c:42
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_taskprocessor * serializer
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_stream_topology * topology
The media stream topology.

◆ chan_pjsip_cng_tone_detected()

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

Internal helper function called when CNG tone is detected.

Definition at line 765 of file chan_pjsip.c.

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

Referenced by chan_pjsip_read_stream().

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

◆ chan_pjsip_devicestate()

static int chan_pjsip_devicestate ( const char *  data)
static

Function called to get the device state of an endpoint.

Definition at line 1174 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

1175 {
1176  RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", data), ao2_cleanup);
1178  RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, NULL, ao2_cleanup);
1179  struct ast_devstate_aggregate aggregate;
1180  int num, inuse = 0;
1181 
1182  if (!endpoint) {
1183  return AST_DEVICE_INVALID;
1184  }
1185 
1186  endpoint_snapshot = ast_endpoint_latest_snapshot(ast_endpoint_get_tech(endpoint->persistent),
1187  ast_endpoint_get_resource(endpoint->persistent));
1188 
1189  if (!endpoint_snapshot) {
1190  return AST_DEVICE_INVALID;
1191  }
1192 
1193  if (endpoint_snapshot->state == AST_ENDPOINT_OFFLINE) {
1194  state = AST_DEVICE_UNAVAILABLE;
1195  } else if (endpoint_snapshot->state == AST_ENDPOINT_ONLINE) {
1196  state = AST_DEVICE_NOT_INUSE;
1197  }
1198 
1199  if (!endpoint_snapshot->num_channels) {
1200  return state;
1201  }
1202 
1203  ast_devstate_aggregate_init(&aggregate);
1204 
1205  for (num = 0; num < endpoint_snapshot->num_channels; num++) {
1206  struct ast_channel_snapshot *snapshot;
1207 
1208  snapshot = ast_channel_snapshot_get_latest(endpoint_snapshot->channel_ids[num]);
1209  if (!snapshot) {
1210  continue;
1211  }
1212 
1213  if (chan_pjsip_get_hold(snapshot->base->uniqueid)) {
1215  } else {
1216  ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
1217  }
1218 
1219  if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
1220  (snapshot->state == AST_STATE_BUSY)) {
1221  inuse++;
1222  }
1223 
1224  ao2_ref(snapshot, -1);
1225  }
1226 
1227  if (endpoint->devicestate_busy_at && (inuse == endpoint->devicestate_busy_at)) {
1228  state = AST_DEVICE_BUSY;
1229  } else if (ast_devstate_aggregate_result(&aggregate) != AST_DEVICE_INVALID) {
1230  state = ast_devstate_aggregate_result(&aggregate);
1231  }
1232 
1233  return state;
1234 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
ast_device_state
Device States.
Definition: devicestate.h:52
struct ast_channel_snapshot_base * base
const char * ast_endpoint_get_tech(const struct ast_endpoint *endpoint)
Gets the technology of the given endpoint.
struct ast_endpoint_snapshot * ast_endpoint_latest_snapshot(const char *tech, const char *resource)
Retrieve the most recent snapshot for the endpoint with the given name.
Structure representing a snapshot of channel state.
const ast_string_field uniqueid
#define NULL
Definition: resample.c:96
const char * ast_endpoint_get_resource(const struct ast_endpoint *endpoint)
Gets the resource name of the given endpoint.
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
Definition: devicestate.c:663
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
enum ast_device_state ast_state_chan2dev(enum ast_channel_state chanstate)
Convert channel state to devicestate.
Definition: devicestate.c:242
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
A snapshot of an endpoint&#39;s state.
void ast_devstate_aggregate_add(struct ast_devstate_aggregate *agg, enum ast_device_state state)
Add a device state to the aggregate device state.
Definition: devicestate.c:636
static int chan_pjsip_get_hold(const char *chan_uid)
Determine whether a channel ID is in the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1161
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
Definition: devicestate.c:630
enum ast_channel_state state
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
You shouldn&#39;t care about the contents of this struct.
Definition: devicestate.h:230

◆ chan_pjsip_digit_begin()

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

Function called by core to start a DTMF digit.

Definition at line 2150 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

2151 {
2153  struct ast_sip_session_media *media;
2154 
2156 
2157  switch (channel->session->dtmf) {
2158  case AST_SIP_DTMF_RFC_4733:
2159  if (!media || !media->rtp) {
2160  return 0;
2161  }
2162 
2164  break;
2165  case AST_SIP_DTMF_AUTO:
2166  if (!media || !media->rtp) {
2167  return 0;
2168  }
2169 
2171  return -1;
2172  }
2173 
2175  break;
2177  if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) {
2178  return 0;
2179  }
2181  break;
2182  case AST_SIP_DTMF_NONE:
2183  break;
2184  case AST_SIP_DTMF_INBAND:
2185  return -1;
2186  default:
2187  break;
2188  }
2189 
2190  return 0;
2191 }
char digit
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
struct ast_sip_session_media_state * active_media_state
enum ast_sip_dtmf_mode dtmf
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2081
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2137

◆ chan_pjsip_digit_end()

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

Function called by core to stop a DTMF digit.

Definition at line 2262 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ao2_cleanup, ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_log, AST_MEDIA_TYPE_AUDIO, AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_NONE, ast_rtp_instance_dtmf_end_with_duration(), ast_rtp_instance_dtmf_mode_get(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_INFO, AST_SIP_DTMF_NONE, AST_SIP_DTMF_RFC_4733, ast_sip_push_task(), ast_sip_session_media_state::default_session, ast_sip_session::dtmf, info_dtmf_data_alloc(), LOG_WARNING, ast_sip_session_media::rtp, ast_sip_session::serializer, ast_sip_channel_pvt::session, and transmit_info_dtmf().

Referenced by chan_pjsip_pvt_dtor().

2263 {
2265  struct ast_sip_session_media *media;
2266 
2267  if (!channel || !channel->session) {
2268  /* This happens when the channel is hungup while a DTMF digit is playing. See ASTERISK-28086 */
2269  ast_debug(3, "Channel %s disappeared while calling digit_end\n", ast_channel_name(ast));
2270  return -1;
2271  }
2272 
2274 
2275  switch (channel->session->dtmf) {
2277  {
2278  if (!media || !media->rtp) {
2279  return 0;
2280  }
2281 
2283  ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));
2285  break;
2286  }
2287  /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */
2288  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));
2289  }
2290 
2291  case AST_SIP_DTMF_INFO:
2292  {
2293  struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
2294 
2295  if (!dtmf_data) {
2296  return -1;
2297  }
2298 
2299  if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
2300  ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
2301  ao2_cleanup(dtmf_data);
2302  return -1;
2303  }
2304  break;
2305  }
2306  case AST_SIP_DTMF_RFC_4733:
2307  if (!media || !media->rtp) {
2308  return 0;
2309  }
2310 
2312  break;
2313  case AST_SIP_DTMF_AUTO:
2314  if (!media || !media->rtp) {
2315  return 0;
2316  }
2317 
2319  return -1;
2320  }
2321 
2323  break;
2324  case AST_SIP_DTMF_NONE:
2325  break;
2326  case AST_SIP_DTMF_INBAND:
2327  return -1;
2328  }
2329 
2330  return 0;
2331 }
char digit
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
unsigned int duration
Definition: chan_pjsip.c:2196
Definition: muted.c:95
struct ast_sip_session_media_state * active_media_state
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int transmit_info_dtmf(void *data)
Definition: chan_pjsip.c:2218
struct ast_taskprocessor * serializer
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
enum ast_sip_dtmf_mode dtmf
static struct info_dtmf_data * info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
Definition: chan_pjsip.c:2205
A structure containing SIP session media information.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2137
int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
Definition: rtp_engine.c:2109

◆ chan_pjsip_fixup()

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

Function called by core to change the underlying owner channel.

Definition at line 1045 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

1046 {
1048 
1049  if (channel->session->channel != oldchan) {
1050  return -1;
1051  }
1052 
1053  /*
1054  * The masquerade has suspended the channel's session
1055  * serializer so we can safely change it outside of
1056  * the serializer thread.
1057  */
1058  channel->session->channel = newchan;
1059 
1061 
1062  return 0;
1063 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:494
struct ast_channel * channel
const char * ast_channel_uniqueid(const struct ast_channel *chan)

◆ chan_pjsip_get_codec()

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

Function called by RTP engine to get peer capabilities.

Definition at line 244 of file chan_pjsip.c.

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

245 {
246  SCOPE_ENTER(1, "%s Native formats %s\n", ast_channel_name(chan),
249  SCOPE_EXIT_RTN();
250 }
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define SCOPE_EXIT_RTN(...)
Scope Exit with return.
Definition: logger.h:854
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269

◆ chan_pjsip_get_hold()

static int chan_pjsip_get_hold ( const char *  chan_uid)
static

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

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

Definition at line 1161 of file chan_pjsip.c.

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

Referenced by chan_pjsip_devicestate().

1162 {
1163  RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1164 
1165  hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1166  if (!hold_uid) {
1167  return 0;
1168  }
1169 
1170  return 1;
1171 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1107
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ chan_pjsip_get_rtp_peer()

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

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

Definition at line 171 of file chan_pjsip.c.

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

172 {
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 }
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
#define ast_assert(a)
Definition: utils.h:695
Definition: muted.c:95
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:766
struct ast_sip_session_media_state * active_media_state
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
#define ao2_ref(o, delta)
Definition: astobj2.h:464
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:711
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.

◆ chan_pjsip_get_uniqueid()

static const char * chan_pjsip_get_uniqueid ( struct ast_channel ast)
static

Definition at line 1278 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

1279 {
1282 
1283  if (!uniqueid) {
1284  return "";
1285  }
1286 
1287  ast_copy_pj_str(uniqueid, &channel->session->inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
1288 
1289  return uniqueid;
1290 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define UNIQUEID_BUFSIZE
Definition: chan_pjsip.c:76
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
struct pjsip_inv_session * inv_session
static struct ast_threadstorage uniqueid_threadbuf
Definition: chan_pjsip.c:75

◆ chan_pjsip_get_vrtp_peer()

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

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

Definition at line 215 of file chan_pjsip.c.

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

216 {
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 }
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
#define ast_assert(a)
Definition: utils.h:695
Definition: muted.c:95
#define NULL
Definition: resample.c:96
struct ast_sip_session_media_state * active_media_state
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
#define ao2_ref(o, delta)
Definition: astobj2.h:464
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:711
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.

◆ chan_pjsip_hangup()

static int chan_pjsip_hangup ( struct ast_channel ast)
static

Function called by core to hang up a PJSIP session.

Definition at line 2516 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

2517 {
2519  int cause;
2520  struct hangup_data *h_data;
2521  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2522 
2523  if (!channel || !channel->session) {
2524  SCOPE_EXIT_RTN_VALUE(-1, "No channel or session\n");
2525  }
2526 
2528  h_data = hangup_data_alloc(cause, ast);
2529 
2530  if (!h_data) {
2531  goto failure;
2532  }
2533 
2534  if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
2535  ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
2536  goto failure;
2537  }
2538 
2539  SCOPE_EXIT_RTN_VALUE(0, "Cause: %d\n", cause);
2540 
2541 failure:
2542  /* Go ahead and do our cleanup of the session and channel even if we're not going
2543  * to be able to send our SIP request/response
2544  */
2545  clear_session_and_channel(channel->session, ast);
2546  ao2_cleanup(channel);
2547  ao2_cleanup(h_data);
2548 
2549  SCOPE_EXIT_RTN_VALUE(-1, "Cause: %d\n", cause);
2550 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
static int hangup_cause2sip(int cause)
Internal function which translates from Asterisk cause codes to SIP response codes.
Definition: chan_pjsip.c:2402
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
static int hangup(void *data)
Definition: chan_pjsip.c:2483
#define ast_log
Definition: astobj2.c:42
struct ast_channel * channel
struct ast_taskprocessor * serializer
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
static struct hangup_data * hangup_data_alloc(int cause, struct ast_channel *chan)
Definition: chan_pjsip.c:2461
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast)
Clear a channel from a session along with its PVT.
Definition: chan_pjsip.c:2476

◆ chan_pjsip_incoming_ack()

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

Definition at line 3241 of file chan_pjsip.c.

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

3242 {
3243  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
3244 
3245  if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
3246  if (session->endpoint->media.direct_media.enabled && session->channel) {
3247  ast_trace(-1, "%s: Queueing SRCCHANGE\n", ast_sip_session_get_name(session));
3249  }
3250  }
3251  SCOPE_EXIT_RTN_VALUE(0, "%s\n", ast_sip_session_get_name(session));
3252 }
struct ast_sip_endpoint * endpoint
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
#define ast_trace(level,...)
Print a basic trace message.
Definition: logger.h:692
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:766
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_channel * channel
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875

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

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_sip_session::channel, ast_sip_session::defer_terminate, ast_sip_session::exten, ast_sip_session::inv_session, transport_info_data::local_addr, LOG_ERROR, NULL, RAII_VAR, transport_info_data::remote_addr, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, and set_sipdomain_variable().

3008 {
3009  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
3010  struct transport_info_data *transport_data;
3011  pjsip_tx_data *packet = NULL;
3012  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
3013 
3014  if (session->channel) {
3015  SCOPE_EXIT_RTN_VALUE(0, "%s: No channel\n", ast_sip_session_get_name(session));
3016  }
3017 
3018  /* Check for a to-tag to determine if this is a reinvite */
3019  if (rdata->msg_info.to->tag.slen) {
3020  /* Weird case. We've received a reinvite but we don't have a channel. The most
3021  * typical case for this happening is that a blind transfer fails, and so the
3022  * transferer attempts to reinvite himself back into the call. We already got
3023  * rid of that channel, and the other side of the call is unrecoverable.
3024  *
3025  * We treat this as a failure, so our best bet is to just hang this call
3026  * up and not create a new channel. Clearing defer_terminate here ensures that
3027  * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
3028  */
3029  session->defer_terminate = 0;
3030  ast_sip_session_terminate(session, 400);
3031  SCOPE_EXIT_RTN_VALUE(-1, "%s: We have a To tag but no channel. Terminating session\n", ast_sip_session_get_name(session));
3032  }
3033 
3034  datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
3035  if (!datastore) {
3036  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info datastore\n", ast_sip_session_get_name(session));
3037  }
3038 
3039  transport_data = ast_calloc(1, sizeof(*transport_data));
3040  if (!transport_data) {
3041  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info\n", ast_sip_session_get_name(session));
3042  }
3043  pj_sockaddr_cp(&transport_data->local_addr, &rdata->tp_info.transport->local_addr);
3044  pj_sockaddr_cp(&transport_data->remote_addr, &rdata->pkt_info.src_addr);
3045  datastore->data = transport_data;
3046  ast_sip_session_add_datastore(session, datastore);
3047 
3048  if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
3049  if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS
3050  && packet) {
3051  ast_sip_session_send_response(session, packet);
3052  }
3053 
3054  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Failed to allocate new PJSIP channel on incoming SIP INVITE\n",
3055  ast_sip_session_get_name(session));
3056  }
3057 
3058  set_sipdomain_variable(session);
3059 
3060  /* channel gets created on incoming request, but we wait to call start
3061  so other supplements have a chance to run */
3062  SCOPE_EXIT_RTN_VALUE(0, "%s\n", ast_sip_session_get_name(session));
3063 }
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
Definition: logger.h:940
pj_sockaddr local_addr
Our address that received the request.
Definition: chan_pjsip.h:34
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
unsigned int defer_terminate
static struct ast_channel * chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
Function called to create a new PJSIP Asterisk channel.
Definition: chan_pjsip.c:547
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
Structure for a data store object.
Definition: datastore.h:68
char exten[AST_MAX_EXTENSION]
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
Transport information stored in transport_info datastore.
Definition: chan_pjsip.h:30
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_channel * channel
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
pj_sockaddr remote_addr
The address that sent the request.
Definition: chan_pjsip.h:32
#define LOG_ERROR
Definition: logger.h:285
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void set_sipdomain_variable(struct ast_sip_session *session)
Definition: chan_pjsip.c:2994
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.

◆ chan_pjsip_incoming_response()

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

Function called when a response is received on the session.

Definition at line 3186 of file chan_pjsip.c.

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, ast_sip_session::channel, ast_sip_session::endpoint, ast_sip_endpoint::ignore_183_without_sdp, SCOPE_ENTER, and SCOPE_EXIT_RTN.

3187 {
3188  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3189  SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3190 
3191  if (!session->channel) {
3192  SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3193  }
3194 
3195  switch (status.code) {
3196  case 180: {
3197  pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3198  if (sdp && sdp->body.ptr) {
3199  ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3201  } else {
3202  ast_trace(-1, "%s: Queueing RINGING\n", ast_sip_session_get_name(session));
3204  }
3205 
3206  ast_channel_lock(session->channel);
3207  if (ast_channel_state(session->channel) != AST_STATE_UP) {
3209  }
3210  ast_channel_unlock(session->channel);
3211  break;
3212  }
3213  case 183:
3214  if (session->endpoint->ignore_183_without_sdp) {
3215  pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3216  if (sdp && sdp->body.ptr) {
3217  ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3218  ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS with SDP\n", ast_sip_session_get_name(session),
3219  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3221  }
3222  } else {
3223  ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3224  ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS without SDP\n", ast_sip_session_get_name(session),
3225  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3227  }
3228  break;
3229  case 200:
3230  ast_trace(-1, "%s: Queueing ANSWER\n", ast_sip_session_get_name(session));
3232  break;
3233  default:
3234  ast_trace(-1, "%s: Not queueing anything\n", ast_sip_session_get_name(session));
3235  break;
3236  }
3237 
3238  SCOPE_EXIT_RTN("%s\n", ast_sip_session_get_name(session));
3239 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_sip_endpoint * endpoint
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
unsigned int ignore_183_without_sdp
Definition: res_pjsip.h:901
#define ast_trace(level,...)
Print a basic trace message.
Definition: logger.h:692
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_channel * channel
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN(...)
Scope Exit with return.
Definition: logger.h:854
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
jack_status_t status
Definition: app_jack.c:146

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

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_sip_session::channel, ast_control_pvt_cause_code::code, hangup_sip2cause(), SCOPE_ENTER, and SCOPE_EXIT_RTN.

3157 {
3158  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3159  struct ast_control_pvt_cause_code *cause_code;
3160  int data_size = sizeof(*cause_code);
3161  SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3162 
3163  if (!session->channel) {
3164  SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3165  }
3166 
3167  /* Build and send the tech-specific cause information */
3168  /* size of the string making up the cause code is "SIP " number + " " + reason length */
3169  data_size += 4 + 4 + pj_strlen(&status.reason);
3170  cause_code = ast_alloca(data_size);
3171  memset(cause_code, 0, data_size);
3172 
3174 
3175  snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
3176  (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
3177 
3178  cause_code->ast_cause = hangup_sip2cause(status.code);
3179  ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
3180  ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
3181 
3182  SCOPE_EXIT_RTN("%s\n", ast_sip_session_get_name(session));
3183 }
char chan_name[AST_CHANNEL_NAME]
static int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_pjsip.c:2860
struct ast_channel * channel
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN(...)
Scope Exit with return.
Definition: logger.h:854
#define AST_CHANNEL_NAME
Definition: channel.h:172
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
int ast_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:1238
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:4391
jack_status_t status
Definition: app_jack.c:146

◆ chan_pjsip_indicate()

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

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

Definition at line 1612 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

1613 {
1615  struct ast_sip_session_media *media;
1616  int response_code = 0;
1617  int res = 0;
1618  char *device_buf;
1619  size_t device_buf_size;
1620  int i;
1621  const struct ast_stream_topology *topology;
1622  struct ast_frame f = {
1624  .subclass = {
1625  .integer = condition
1626  },
1627  .datalen = datalen,
1628  .data.ptr = (void *)data,
1629  };
1630  char condition_name[256];
1631  SCOPE_ENTER(3, "%s: Indicated %s\n", ast_channel_name(ast),
1632  ast_frame_subclass2str(&f, condition_name, sizeof(condition_name), NULL, 0));
1633 
1634  switch (condition) {
1635  case AST_CONTROL_RINGING:
1636  if (ast_channel_state(ast) == AST_STATE_RING) {
1637  if (channel->session->endpoint->inband_progress ||
1638  (channel->session->inv_session && channel->session->inv_session->neg &&
1639  pjmedia_sdp_neg_get_state(channel->session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE)) {
1640  response_code = 183;
1641  res = -1;
1642  } else {
1643  response_code = 180;
1644  }
1645  } else {
1646  res = -1;
1647  }
1649  break;
1650  case AST_CONTROL_BUSY:
1651  if (ast_channel_state(ast) != AST_STATE_UP) {
1652  response_code = 486;
1653  } else {
1654  res = -1;
1655  }
1656  break;
1658  if (ast_channel_state(ast) != AST_STATE_UP) {
1659  response_code = 503;
1660  } else {
1661  res = -1;
1662  }
1663  break;
1665  if (ast_channel_state(ast) != AST_STATE_UP) {
1666  response_code = 484;
1667  } else {
1668  res = -1;
1669  }
1670  break;
1672  if (ast_channel_state(ast) != AST_STATE_UP) {
1673  response_code = 100;
1674  } else {
1675  res = -1;
1676  }
1677  break;
1678  case AST_CONTROL_PROGRESS:
1679  if (ast_channel_state(ast) != AST_STATE_UP) {
1680  response_code = 183;
1681  } else {
1682  res = -1;
1683  }
1685  break;
1686  case AST_CONTROL_VIDUPDATE:
1687  for (i = 0; i < AST_VECTOR_SIZE(&channel->session->active_media_state->sessions); ++i) {
1688  media = AST_VECTOR_GET(&channel->session->active_media_state->sessions, i);
1689  if (!media || media->type != AST_MEDIA_TYPE_VIDEO) {
1690  continue;
1691  }
1692  if (media->rtp) {
1693  /* FIXME: Only use this for VP8. Additional work would have to be done to
1694  * fully support other video codecs */
1695 
1699  (channel->session->endpoint->media.webrtc &&
1701  /* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
1702  * RTP engine would provide a way to externally write/schedule RTCP
1703  * packets */
1704  struct ast_frame fr;
1706  fr.subclass.integer = AST_CONTROL_VIDUPDATE;
1707  res = ast_rtp_instance_write(media->rtp, &fr);
1708  } else {
1709  ao2_ref(channel->session, +1);
1711  ao2_cleanup(channel->session);
1712  }
1713  }
1714  ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
1715  } else {
1716  ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
1717  res = -1;
1718  }
1719  }
1720  /* XXX If there were no video streams, then this should set
1721  * res to -1
1722  */
1723  break;
1725  ao2_ref(channel->session, +1);
1727  ao2_cleanup(channel->session);
1728  }
1729  break;
1731  break;
1733  res = -1;
1734  break;
1736  ast_assert(datalen == sizeof(int));
1737  if (*(int *) data) {
1738  /*
1739  * Masquerade is beginning:
1740  * Wait for session serializer to get suspended.
1741  */
1742  ast_channel_unlock(ast);
1743  ast_sip_session_suspend(channel->session);
1744  ast_channel_lock(ast);
1745  } else {
1746  /*
1747  * Masquerade is complete:
1748  * Unsuspend the session serializer.
1749  */
1751  }
1752  break;
1753  case AST_CONTROL_HOLD:
1755  device_buf_size = strlen(ast_channel_name(ast)) + 1;
1756  device_buf = alloca(device_buf_size);
1757  ast_channel_get_device_name(ast, device_buf, device_buf_size);
1759  if (!channel->session->moh_passthrough) {
1760  ast_moh_start(ast, data, NULL);
1761  } else {
1763  ast_log(LOG_WARNING, "Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
1765  ao2_ref(channel->session, -1);
1766  }
1767  }
1768  break;
1769  case AST_CONTROL_UNHOLD:
1771  device_buf_size = strlen(ast_channel_name(ast)) + 1;
1772  device_buf = alloca(device_buf_size);
1773  ast_channel_get_device_name(ast, device_buf, device_buf_size);
1775  if (!channel->session->moh_passthrough) {
1776  ast_moh_stop(ast);
1777  } else {
1779  ast_log(LOG_WARNING, "Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
1781  ao2_ref(channel->session, -1);
1782  }
1783  }
1784  break;
1785  case AST_CONTROL_SRCUPDATE:
1786  break;
1787  case AST_CONTROL_SRCCHANGE:
1788  break;
1790  if (ast_channel_state(ast) != AST_STATE_UP) {
1791  response_code = 181;
1792  } else {
1793  res = -1;
1794  }
1795  break;
1797  res = 0;
1798 
1799  if (channel->session->t38state == T38_PEER_REINVITE) {
1800  const struct ast_control_t38_parameters *parameters = data;
1801 
1802  if (parameters->request_response == AST_T38_REQUEST_PARMS) {
1803  res = AST_T38_REQUEST_PARMS;
1804  }
1805  }
1806 
1807  break;
1809  topology = data;
1810  ast_trace(-1, "%s: New topology: %s\n", ast_channel_name(ast),
1811  ast_str_tmp(256, ast_stream_topology_to_str(topology, &STR_TMP)));
1812  res = handle_topology_request_change(channel->session, topology);
1813  break;
1815  break;
1817  break;
1818  case -1:
1819  res = -1;
1820  break;
1821  default:
1822  ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
1823  res = -1;
1824  break;
1825  }
1826 
1827  if (response_code) {
1828  struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
1829 
1830  if (!ind_data) {
1831  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
1832  }
1833 
1834  if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
1835  ast_log(LOG_ERROR, "%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
1836  ast_channel_name(ast), response_code, ast_sorcery_object_get_id(channel->session->endpoint));
1837  ao2_cleanup(ind_data);
1838  res = -1;
1839  }
1840  }
1841 
1842  SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_channel_name(ast));
1843 }
static int remote_send_hold(void *data)
Update local hold state to be held.
Definition: chan_pjsip.c:1500
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:196
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
Definition: logger.h:940
enum ast_sip_session_t38state t38state
#define ast_channel_lock(chan)
Definition: channel.h:2945
static int indicate(void *data)
Definition: chan_pjsip.c:1333
struct ast_sip_endpoint * endpoint
static int transmit_info_with_vidupdate(void *data)
Send SIP INFO with video update request.
Definition: chan_pjsip.c:1351
void ast_sip_session_unsuspend(struct ast_sip_session *session)
Request the session serializer be unsuspended.
static int remote_send_unhold(void *data)
Update local hold state to be unheld.
Definition: chan_pjsip.c:1506
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_sip_session_suspend(struct ast_sip_session *session)
Request and wait for the session serializer to be suspended.
#define LOG_WARNING
Definition: logger.h:274
static int chan_pjsip_add_hold(const char *chan_uid)
Add a channel ID to the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1117
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
static struct indicate_data * indicate_data_alloc(struct ast_sip_session *session, int condition, int response_code, const void *frame_data, size_t datalen)
Definition: chan_pjsip.c:1308
enum ast_control_t38 request_response
#define ast_trace(level,...)
Print a basic trace message.
Definition: logger.h:692
ast_channel_state
ast_channel states
Definition: channelstate.h:35
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
#define ast_assert(a)
Definition: utils.h:695
Definition: muted.c:95
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
unsigned int inband_progress
Definition: res_pjsip.h:863
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:1148
static int update_connected_line_information(void *data)
Update connected line information.
Definition: chan_pjsip.c:1429
struct ast_sip_session_media_state * active_media_state
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_log
Definition: astobj2.c:42
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
size_t datalen
Definition: chan_pjsip.c:1297
#define ao2_ref(o, delta)
Definition: astobj2.h:464
char * ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
Copy the discription of a frame&#39;s subclass into the provided string.
Definition: main/frame.c:406
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ast_taskprocessor * serializer
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
struct ast_format * ast_format_vp9
Built-in cached vp9 format.
Definition: format_cache.c:201
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
struct ast_format * ast_format_h264
Built-in cached h264 format.
Definition: format_cache.c:181
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
A structure containing SIP session media information.
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
struct ast_format * ast_format_h265
Built-in cached h265 format.
Definition: format_cache.c:186
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
enum ast_media_type type
Media type of this session media.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
static int handle_topology_request_change(struct ast_sip_session *session, const struct ast_stream_topology *proposed)
Definition: chan_pjsip.c:1592
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:10697
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:471
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
unsigned int moh_passthrough

◆ chan_pjsip_new()

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

Function called to create a new PJSIP Asterisk channel.

Definition at line 547 of file chan_pjsip.c.

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

Referenced by chan_pjsip_incoming_request(), and chan_pjsip_request_with_stream_topology().

548 {
549  struct ast_channel *chan;
550  struct ast_format_cap *caps;
551  RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
553  struct ast_variable *var;
554  struct ast_stream_topology *topology;
555  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
556 
557  if (!(pvt = ao2_alloc_options(sizeof(*pvt), chan_pjsip_pvt_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK))) {
558  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt\n");
559  }
560 
562  S_COR(session->id.number.valid, session->id.number.str, ""),
563  S_COR(session->id.name.valid, session->id.name.str, ""),
564  session->endpoint->accountcode,
565  exten, session->endpoint->context,
566  assignedids, requestor, 0,
567  session->endpoint->persistent, "PJSIP/%s-%08x",
569  (unsigned) ast_atomic_fetchadd_int((int *) &chan_idx, +1));
570  if (!chan) {
571  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
572  }
573 
575 
576  if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
577  ast_channel_unlock(chan);
578  ast_hangup(chan);
579  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt channel\n");
580  }
581 
582  ast_channel_tech_pvt_set(chan, channel);
583 
587  if (!caps) {
588  ast_channel_unlock(chan);
589  ast_hangup(chan);
590  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create caps\n");
591  }
593  topology = ast_stream_topology_clone(session->endpoint->media.topology);
594  } else {
597  }
598 
599  if (!topology || !caps) {
600  ao2_cleanup(caps);
601  ast_stream_topology_free(topology);
602  ast_channel_unlock(chan);
603  ast_hangup(chan);
604  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't get caps or clone topology\n");
605  }
606 
608 
609  ast_channel_nativeformats_set(chan, caps);
610  ast_channel_set_stream_topology(chan, topology);
611 
612  if (!ast_format_cap_empty(caps)) {
613  struct ast_format *fmt;
614 
616  if (!fmt) {
617  /* Since our capabilities aren't empty, this will succeed */
618  fmt = ast_format_cap_get_format(caps, 0);
619  }
620  ast_channel_set_writeformat(chan, fmt);
622  ast_channel_set_readformat(chan, fmt);
624  ao2_ref(fmt, -1);
625  }
626 
627  ao2_ref(caps, -1);
628 
629  if (state == AST_STATE_RING) {
630  ast_channel_rings_set(chan, 1);
631  }
632 
634 
635  ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id);
636  ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id);
637 
638  if (!ast_strlen_zero(exten)) {
639  /* Set provided DNID on the new channel. */
641  }
642 
643  ast_channel_priority_set(chan, 1);
644 
647 
650 
651  if (!ast_strlen_zero(session->endpoint->language)) {
652  ast_channel_language_set(chan, session->endpoint->language);
653  }
654 
655  if (!ast_strlen_zero(session->endpoint->zone)) {
656  struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
657  if (!zone) {
658  ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
659  }
660  ast_channel_zone_set(chan, zone);
661  }
662 
663  for (var = session->endpoint->channel_vars; var; var = var->next) {
664  char buf[512];
666  var->value, buf, sizeof(buf)));
667  }
668 
670  ast_channel_unlock(chan);
671 
673 
674  SCOPE_EXIT_RTN_VALUE(chan);
675 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
struct ast_sip_endpoint_pickup_configuration pickup
Definition: res_pjsip.h:851
struct ast_variable * next
static unsigned int chan_idx
Definition: chan_pjsip.c:80
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
struct ast_party_dialed::@246 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
char * str
Subscriber phone number (Malloced)
Definition: channel.h:387
static void chan_pjsip_pvt_dtor(void *obj)
Definition: chan_pjsip.c:82
struct ast_sip_session_media_state * pending_media_state
#define ast_channel_alloc_with_endpoint(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint,...)
Definition: channel.h:1263
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:3002
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
Definition: stream.c:930
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition: channel.c:1765
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
struct ast_format_cap * codecs
Definition: res_pjsip.h:770
const ast_string_field context
Definition: res_pjsip.h:815
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
char * str
Subscriber name (Malloced)
Definition: channel.h:265
A structure which contains a channel implementation and session.
Definition of a media format.
Definition: format.c:43
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition: format_cap.c:417
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
Definition: muted.c:95
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:494
struct ast_namedgroups * named_pickupgroups
Definition: res_pjsip.h:663
void ast_channel_rings_set(struct ast_channel *chan, int value)
static int compatible_formats_exist(struct ast_stream_topology *top, struct ast_format_cap *cap)
Determine if a topology is compatible with format capabilities.
Definition: chan_pjsip.c:526
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
A set of tones for a given locale.
Definition: indications.h:74
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
const ast_string_field language
Definition: res_pjsip.h:827
struct ast_sip_channel_pvt * ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session)
Allocate a new SIP channel pvt structure.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
const ast_string_field accountcode
Definition: res_pjsip.h:835
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ast_namedgroups * named_callgroups
Definition: res_pjsip.h:661
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
const ast_string_field zone
Definition: res_pjsip.h:825
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define LOG_ERROR
Definition: logger.h:285
struct ast_stream_topology * ast_channel_set_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Set the topology of streams on a channel.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:433
The PJSIP channel driver pvt, stored in the ast_sip_channel_pvt data structure.
Definition: chan_pjsip.h:42
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
struct ast_endpoint * persistent
Definition: res_pjsip.h:865
struct ast_stream_topology * topology
Definition: res_pjsip.h:772
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_stream_topology * topology
The media stream topology.
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:746
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
struct ast_variable * channel_vars
Definition: res_pjsip.h:875
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
struct ast_party_id id
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ chan_pjsip_pvt_dtor()

static void chan_pjsip_pvt_dtor ( void *  obj)
static

◆ chan_pjsip_queryoption()

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

Function called to query options on a channel.

Definition at line 1237 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

1238 {
1240  int res = -1;
1242 
1243  if (!channel) {
1244  return -1;
1245  }
1246 
1247  switch (option) {
1248  case AST_OPTION_T38_STATE:
1249  if (channel->session->endpoint->media.t38.enabled) {
1250  switch (channel->session->t38state) {
1251  case T38_LOCAL_REINVITE:
1252  case T38_PEER_REINVITE:
1253  state = T38_STATE_NEGOTIATING;
1254  break;
1255  case T38_ENABLED:
1256  state = T38_STATE_NEGOTIATED;
1257  break;
1258  case T38_REJECTED:
1259  state = T38_STATE_REJECTED;
1260  break;
1261  default:
1262  state = T38_STATE_UNKNOWN;
1263  break;
1264  }
1265  }
1266 
1267  *((enum ast_t38_state *) data) = state;
1268  res = 0;
1269 
1270  break;
1271  default:
1272  break;
1273  }
1274 
1275  return res;
1276 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
enum ast_sip_session_t38state t38state
#define T38_ENABLED
Definition: chan_ooh323.c:102
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:879
Definition: muted.c:95
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_sip_t38_configuration t38
Definition: res_pjsip.h:768
#define AST_OPTION_T38_STATE

◆ chan_pjsip_read_stream()

static struct ast_frame * chan_pjsip_read_stream ( struct ast_channel ast)
static

Function called by core to read any waiting frames.

Note
The channel is already locked.

Definition at line 838 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

839 {
841  struct ast_sip_session *session = channel->session;
842  struct ast_sip_session_media_read_callback_state *callback_state;
843  struct ast_frame *f;
844  int fdno = ast_channel_fdno(ast) - AST_EXTENDED_FDS;
845  struct ast_frame *cur;
846 
847  if (fdno >= AST_VECTOR_SIZE(&session->active_media_state->read_callbacks)) {
848  return &ast_null_frame;
849  }
850 
851  callback_state = AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, fdno);
852  f = callback_state->read_callback(session, callback_state->session);
853 
854  if (!f) {
855  return f;
856  }
857 
858  for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
859  if (cur->frametype == AST_FRAME_VOICE) {
860  break;
861  }
862  }
863 
864  if (!cur || callback_state->session != session->active_media_state->default_session[callback_state->session->type]) {
865  return f;
866  }
867 
868  session = channel->session;
869 
870  /*
871  * Asymmetric RTP only has one native format set at a time.
872  * Therefore we need to update the native format to the current
873  * raw read format BEFORE the native format check
874  */
875  if (!session->endpoint->asymmetric_rtp_codec &&
877  is_compatible_format(session, cur)) {
878  struct ast_format_cap *caps;
879 
880  /* For maximum compatibility we ensure that the formats match that of the received media */
881  ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n",
884 
886  if (caps) {
889  ast_format_cap_append(caps, cur->subclass.format, 0);
891  ao2_ref(caps, -1);
892  }
893 
896 
897  if (ast_channel_is_bridged(ast)) {
899  }
900  }
901 
904  ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n",
906  ast_frfree(f);
907  return &ast_null_frame;
908  }
909 
910  if (session->dsp) {
911  int dsp_features;
912 
913  dsp_features = ast_dsp_get_features(session->dsp);
914  if ((dsp_features & DSP_FEATURE_FAX_DETECT)
915  && session->endpoint->faxdetect_timeout
916  && session->endpoint->faxdetect_timeout <= ast_channel_get_up_time(ast)) {
917  dsp_features &= ~DSP_FEATURE_FAX_DETECT;
918  if (dsp_features) {
919  ast_dsp_set_features(session->dsp, dsp_features);
920  } else {
921  ast_dsp_free(session->dsp);
922  session->dsp = NULL;
923  }
924  ast_debug(3, "Channel driver fax CNG detection timeout on %s\n",
925  ast_channel_name(ast));
926  }
927  }
928  if (session->dsp) {
929  f = ast_dsp_process(ast, session->dsp, f);
930  if (f && (f->frametype == AST_FRAME_DTMF)) {
931  if (f->subclass.integer == 'f') {
932  ast_debug(3, "Channel driver fax CNG detected on %s\n",
933  ast_channel_name(ast));
934  f = chan_pjsip_cng_tone_detected(ast, session, f);
935  /* When chan_pjsip_cng_tone_detected returns it is possible for the
936  * channel pointed to by ast and by session->channel to differ due to a
937  * masquerade. It's best not to touch things after this.
938  */
939  } else {
940  ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
941  ast_channel_name(ast));
942  }
943  }
944  }
945 
946  return f;
947 }
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:1494
struct ast_sip_endpoint * endpoint
static int is_compatible_format(struct ast_sip_session *session, struct ast_frame *f)
Determine if the given frame is in a format we&#39;ve negotiated.
Definition: chan_pjsip.c:824
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
unsigned int asymmetric_rtp_codec
Definition: res_pjsip.h:891
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2854
Definition: muted.c:95
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
A structure describing a SIP session.
struct ast_frame_subclass subclass
static struct ast_frame * chan_pjsip_cng_tone_detected(struct ast_channel *ast, struct ast_sip_session *session, struct ast_frame *f)
Internal helper function called when CNG tone is detected.
Definition: chan_pjsip.c:765
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:5575
struct ast_sip_session_media_state * active_media_state
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
struct ast_dsp * dsp
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1764
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:670
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
ast_sip_session_media_read_cb read_callback
The callback to invoke.
struct ast_sip_session_media * session
The media session.
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
Structure which contains read callback information.
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
int ast_channel_fdno(const struct ast_channel *chan)
#define AST_EXTENDED_FDS
Definition: channel.h:196
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
unsigned int faxdetect_timeout
Definition: res_pjsip.h:885
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
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:5611
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_frame ast_null_frame
Definition: main/frame.c:79
enum ast_media_type type
Media type of this session media.
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
Data structure associated with a single frame of data.
enum ast_frame_type frametype
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_format * format
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ chan_pjsip_remove_hold()

static void chan_pjsip_remove_hold ( const char *  chan_uid)
static

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

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

Definition at line 1148 of file chan_pjsip.c.

References ao2_find, OBJ_NODATA, OBJ_SEARCH_KEY, and OBJ_UNLINK.

Referenced by chan_pjsip_indicate(), and chan_pjsip_session_end().

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

◆ chan_pjsip_request()

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

Definition at line 2694 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

2695 {
2696  struct ast_stream_topology *topology;
2697  struct ast_channel *chan;
2698 
2700  if (!topology) {
2701  return NULL;
2702  }
2703 
2704  chan = chan_pjsip_request_with_stream_topology(type, topology, assignedids, requestor, data, cause);
2705 
2706  ast_stream_topology_free(topology);
2707 
2708  return chan;
2709 }
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
struct ast_stream_topology * ast_stream_topology_create_from_format_cap(struct ast_format_cap *cap)
A helper function that, given a format capabilities structure, creates a topology and separates the m...
Definition: stream.c:848
#define NULL
Definition: resample.c:96
const char * data
static struct ast_channel * chan_pjsip_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Function called by core to create a new outgoing PJSIP session.
Definition: chan_pjsip.c:2667
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743

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

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

Referenced by chan_pjsip_pvt_dtor(), and chan_pjsip_request().

2668 {
2669  struct request_data req_data;
2671  SCOPE_ENTER(1, "%s Topology: %s\n", data,
2672  ast_str_tmp(256, ast_stream_topology_to_str(topology, &STR_TMP)));
2673 
2674  req_data.topology = topology;
2675  req_data.dest = data;
2676  /* Default failure value in case ast_sip_push_task_wait_servant() itself fails. */
2677  req_data.cause = AST_CAUSE_FAILURE;
2678 
2679  if (ast_sip_push_task_wait_servant(NULL, request, &req_data)) {
2680  *cause = req_data.cause;
2681  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't push task\n");
2682  }
2683 
2684  session = req_data.session;
2685 
2686  if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
2687  /* Session needs to be terminated prematurely */
2688  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
2689  }
2690 
2691  SCOPE_EXIT_RTN_VALUE(session->channel, "Channel: %s\n", ast_channel_name(session->channel));
2692 }
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:547
#define NULL
Definition: resample.c:96
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:5204
A structure describing a SIP session.
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct ast_mansession session
#define AST_CAUSE_FAILURE
Definition: causes.h:149
struct ast_stream_topology * topology
Definition: chan_pjsip.c:2554
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
static int request(void *obj)
Definition: chan_pjsip.c:2559
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)

◆ chan_pjsip_sendtext()

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

Definition at line 2837 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

2838 {
2839  struct ast_msg_data *msg;
2840  int rc;
2841  struct ast_msg_data_attribute attrs[] =
2842  {
2843  {
2845  .value = (char *)text,
2846  }
2847  };
2848 
2850  if (!msg) {
2851  return -1;
2852  }
2853  rc = chan_pjsip_sendtext_data(ast, msg);
2854  ast_free(msg);
2855 
2856  return rc;
2857 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
enum ast_msg_data_attribute_type type
Definition: message.h:463
Structure used to transport a message through the frame core.
Definition: message.c:1406
struct ast_msg_data * ast_msg_data_alloc(enum ast_msg_data_source_type source, struct ast_msg_data_attribute attributes[], size_t count)
Allocates an ast_msg_data structure.
Definition: message.c:1418
char * text
Definition: app_queue.c:1508
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:2815
#define ast_free(a)
Definition: astmm.h:182

◆ chan_pjsip_sendtext_data()

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

Function called by core to send text on PJSIP session.

Definition at line 2815 of file chan_pjsip.c.

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(), sendtext_data_create(), ast_sip_session::serializer, and ast_sip_channel_pvt::session.

Referenced by chan_pjsip_pvt_dtor(), and chan_pjsip_sendtext().

2816 {
2818  struct sendtext_data *data = sendtext_data_create(ast, msg);
2819 
2820  ast_debug(1, "Sending MESSAGE from '%s' to '%s:%s': %s\n",
2823  ast_channel_name(ast),
2825 
2826  if (!data) {
2827  return -1;
2828  }
2829 
2830  if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
2831  ao2_ref(data, -1);
2832  return -1;
2833  }
2834  return 0;
2835 }
static struct sendtext_data * sendtext_data_create(struct ast_channel *chan, struct ast_msg_data *msg)
Definition: chan_pjsip.c:2723
void * ast_channel_tech_pvt(const struct ast_channel *chan)
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_taskprocessor * serializer
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
Definition: message.c:1533
const char * ast_channel_name(const struct ast_channel *chan)
static int sendtext(void *obj)
Definition: chan_pjsip.c:2744

◆ chan_pjsip_session_begin()

static void chan_pjsip_session_begin ( struct ast_sip_session session)
static

SIP session interaction functions.

Definition at line 2950 of file chan_pjsip.c.

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

2951 {
2952  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
2953  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
2954 
2955  if (session->endpoint->media.direct_media.glare_mitigation ==
2957  SCOPE_EXIT_RTN("Direct media no glare mitigation\n");
2958  }
2959 
2961  "direct_media_glare_mitigation");
2962 
2963  if (!datastore) {
2964  SCOPE_EXIT_RTN("Couldn't create datastore\n");
2965  }
2966 
2967  ast_sip_session_add_datastore(session, datastore);
2968  SCOPE_EXIT_RTN();
2969 }
struct ast_sip_endpoint * endpoint
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
static struct ast_datastore_info direct_media_mitigation_info
Definition: chan_pjsip.c:266
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:766
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN(...)
Scope Exit with return.
Definition: logger.h:854
enum ast_sip_direct_media_glare_mitigation glare_mitigation
Definition: res_pjsip.h:735
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.

◆ chan_pjsip_session_end()

static void chan_pjsip_session_end ( struct ast_sip_session session)
static

Function called when the session ends.

Definition at line 2972 of file chan_pjsip.c.

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

2973 {
2974  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
2975 
2976  if (!session->channel) {
2977  SCOPE_EXIT_RTN("No channel\n");
2978  }
2979 
2981 
2982  ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2983  if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
2984  int cause = hangup_sip2cause(session->inv_session->cause);
2985 
2986  ast_queue_hangup_with_cause(session->channel, cause);
2987  } else {
2988  ast_queue_hangup(session->channel);
2989  }
2990 
2991  SCOPE_EXIT_RTN();
2992 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
struct pjsip_inv_session * inv_session
static void chan_pjsip_remove_hold(const char *chan_uid)
Remove a channel ID from the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1148
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
static int hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: chan_pjsip.c:2860
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2504
struct ast_channel * channel
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_EXIT_RTN(...)
Scope Exit with return.
Definition: logger.h:854
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)

◆ chan_pjsip_set_rtp_peer()

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

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

Definition at line 448 of file chan_pjsip.c.

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

454 {
456  struct ast_sip_session *session = channel->session;
458  SCOPE_ENTER(1, "%s %s\n", ast_channel_name(chan),
460 
461  /* Don't try to do any direct media shenanigans on early bridges */
462  if ((rtp || vrtp || tpeer) && !ast_channel_is_bridged(chan)) {
463  ast_debug(4, "Disregarding setting RTP on %s: channel is not bridged\n", ast_channel_name(chan));
464  SCOPE_EXIT_RTN_VALUE(0, "Channel not bridged\n");
465  }
466 
467  if (nat_active && session->endpoint->media.direct_media.disable_on_nat) {
468  ast_debug(4, "Disregarding setting RTP on %s: NAT is active\n", ast_channel_name(chan));
469  SCOPE_EXIT_RTN_VALUE(0, "NAT is active\n");
470  }
471 
472  cdata = rtp_direct_media_data_create(chan, rtp, vrtp, cap, session);
473  if (!cdata) {
475  }
476 
478  ast_log(LOG_ERROR, "Unable to send direct media request for channel %s\n", ast_channel_name(chan));
479  ao2_ref(cdata, -1);
480  }
481 
483 }
struct ast_sip_endpoint * endpoint
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:766
A structure describing a SIP session.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int send_direct_media_request(void *data)
Definition: chan_pjsip.c:396
struct ast_taskprocessor * serializer
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
static int cdata(void *userdata, int state, const char *cdata, size_t len)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
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:377
const char * ast_channel_name(const struct ast_channel *chan)

◆ chan_pjsip_transfer()

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

Function called by core for Asterisk initiated transfer.

Definition at line 2131 of file chan_pjsip.c.

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

Referenced by chan_pjsip_pvt_dtor().

2132 {
2134  struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
2135 
2136  if (!trnf_data) {
2137  return -1;
2138  }
2139 
2140  if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
2141  ast_log(LOG_WARNING, "Error requesting transfer\n");
2142  ao2_cleanup(trnf_data);
2143  return -1;
2144  }
2145 
2146  return 0;
2147 }
static int transfer(void *data)
Definition: chan_pjsip.c:2096
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
static struct transfer_data * transfer_data_alloc(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1858
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define ast_log
Definition: astobj2.c:42
struct ast_taskprocessor * serializer
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ chan_pjsip_write()

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

Definition at line 1039 of file chan_pjsip.c.

References chan_pjsip_write_stream().

Referenced by chan_pjsip_pvt_dtor().

1040 {
1041  return chan_pjsip_write_stream(ast, -1, frame);
1042 }
static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f)
Definition: chan_pjsip.c:949

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

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

Referenced by chan_pjsip_pvt_dtor(), and chan_pjsip_write().

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

◆ check_for_rtp_changes()

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

Definition at line 319 of file chan_pjsip.c.

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

Referenced by send_direct_media_request().

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) {
340  /* Direct media has ended - reset time of last received RTP packet
341  * to avoid premature RTP timeout. Synchronisation between the
342  * modification of direct_mdedia_addr+last_rx here and reading the
343  * values in res_pjsip_sdp_rtp.c:rtp_check_timeout() is provided
344  * by the channel's lock (which is held while this function is
345  * executed).
346  */
347  ast_rtp_instance_set_last_rx(media->rtp, time(NULL));
349  if (position != -1) {
350  ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, ast_rtp_instance_fd(media->rtp, 1));
351  }
352  }
353  }
354 
355  return changed;
356 }
struct ast_sockaddr direct_media_addr
Direct media address.
#define NULL
Definition: resample.c:96
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define AST_EXTENDED_FDS
Definition: channel.h:196
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
struct ast_rtp_instance * rtp
RTP instance itself.
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
static int rtp_find_rtcp_fd_position(struct ast_sip_session *session, struct ast_rtp_instance *rtp)
Helper function to find the position for RTCP.
Definition: chan_pjsip.c:298
#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_last_rx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP reception time.
Definition: rtp_engine.c:3773

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

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

Referenced by chan_pjsip_hangup(), and hangup().

2477 {
2478  session->channel = NULL;
2479  set_channel_on_rtp_instance(session, "");
2481 }
#define NULL
Definition: resample.c:96
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:494
struct ast_channel * channel
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

◆ compatible_formats_exist()

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

Determine if a topology is compatible with format capabilities.

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

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

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

Definition at line 526 of file chan_pjsip.c.

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

Referenced by chan_pjsip_new().

527 {
528  struct ast_format_cap *cap_from_top;
529  int res;
530  SCOPE_ENTER(1, "Topology: %s Formats: %s\n",
533 
534  cap_from_top = ast_stream_topology_get_formats(top);
535 
536  if (!cap_from_top) {
537  SCOPE_EXIT_RTN_VALUE(0, "Topology had no formats\n");
538  }
539 
540  res = ast_format_cap_iscompatible(cap_from_top, cap);
541  ao2_ref(cap_from_top, -1);
542 
543  SCOPE_EXIT_RTN_VALUE(res, "Compatible? %s\n", res ? "yes" : "no");
544 }
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
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition: format_cap.c:655

◆ direct_media_mitigate_glare()

static int direct_media_mitigate_glare ( struct ast_sip_session session)
static

Definition at line 268 of file chan_pjsip.c.

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

Referenced by send_direct_media_request().

269 {
270  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
271 
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) ||
290  session->inv_session->role == PJSIP_ROLE_UAS)) {
291  return 1;
292  }
293 
294  return 0;
295 }
struct ast_sip_endpoint * endpoint
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:766
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
enum ast_sip_direct_media_glare_mitigation glare_mitigation
Definition: res_pjsip.h:735
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ handle_topology_request_change()

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

Definition at line 1592 of file chan_pjsip.c.

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

Referenced by chan_pjsip_indicate().

1594 {
1596  int res;
1597  SCOPE_ENTER(1);
1598 
1599  refresh_data = topology_change_refresh_data_alloc(session, proposed);
1600  if (!refresh_data) {
1601  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create refresh_data\n");
1602  }
1603 
1604  res = ast_sip_push_task(session->serializer, send_topology_change_refresh, refresh_data);
1605  if (res) {
1606  topology_change_refresh_data_free(refresh_data);
1607  }
1608  SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
1609 }
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:1524
static int send_topology_change_refresh(void *data)
Definition: chan_pjsip.c:1575
struct ast_taskprocessor * serializer
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
Definition: chan_pjsip.c:1516

◆ hangup()

static int hangup ( void *  data)
static

Definition at line 2483 of file chan_pjsip.c.

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

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

2484 {
2485  struct hangup_data *h_data = data;
2486  struct ast_channel *ast = h_data->chan;
2488  SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2489 
2490  /*
2491  * Before cleaning we have to ensure that channel or its session is not NULL
2492  * we have seen rare case when taskprocessor calls hangup but channel is NULL
2493  * due to SIP session timeout and answer happening at the same time
2494  */
2495  if (channel) {
2496  struct ast_sip_session *session = channel->session;
2497  if (session) {
2498  int cause = h_data->cause;
2499 
2500  /*
2501  * It's possible that session_terminate might cause the session to be destroyed
2502  * immediately so we need to keep a reference to it so we can NULL session->channel
2503  * afterwards.
2504  */
2505  ast_sip_session_terminate(ao2_bump(session), cause);
2506  clear_session_and_channel(session, ast);
2507  ao2_cleanup(session);
2508  }
2509  ao2_cleanup(channel);
2510  }
2511  ao2_cleanup(h_data);
2513 }
Main Channel structure associated with a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
A structure describing a SIP session.
#define ao2_bump(obj)
Definition: astobj2.h:491
static struct ast_mansession session
struct ast_channel * chan
Definition: chan_pjsip.c:2451
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast)
Clear a channel from a session along with its PVT.
Definition: chan_pjsip.c:2476

◆ hangup_cause2sip()

static int hangup_cause2sip ( int  cause)
static

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

Definition at line 2402 of file chan_pjsip.c.

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

Referenced by chan_pjsip_hangup().

2403 {
2404  switch (cause) {
2405  case AST_CAUSE_UNALLOCATED: /* 1 */
2406  case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
2407  case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
2408  return 404;
2409  case AST_CAUSE_CONGESTION: /* 34 */
2410  case AST_CAUSE_SWITCH_CONGESTION: /* 42 */
2411  return 503;
2412  case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
2413  return 408;
2414  case AST_CAUSE_NO_ANSWER: /* 19 */
2415  case AST_CAUSE_UNREGISTERED: /* 20 */
2416  return 480;
2417  case AST_CAUSE_CALL_REJECTED: /* 21 */
2418  return 403;
2419  case AST_CAUSE_NUMBER_CHANGED: /* 22 */
2420  return 410;
2421  case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */
2422  return 480;
2424  return 484;
2425  case AST_CAUSE_USER_BUSY:
2426  return 486;
2427  case AST_CAUSE_FAILURE:
2428  return 500;
2429  case AST_CAUSE_FACILITY_REJECTED: /* 29 */
2430  return 501;
2432  return 503;
2434  return 502;
2435  case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
2436  return 488;
2437  case AST_CAUSE_INTERWORKING: /* Unspecified Interworking issues */
2438  return 500;
2439  case AST_CAUSE_NOTDEFINED:
2440  default:
2441  ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
2442  return 0;
2443  }
2444 
2445  /* Never reached */
2446  return 0;
2447 }
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
#define AST_CAUSE_FACILITY_REJECTED
Definition: causes.h:116
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:107
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
Definition: causes.h:98
#define AST_CAUSE_CHAN_NOT_IMPLEMENTED
Definition: causes.h:131
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
#define AST_CAUSE_NOTDEFINED
Definition: causes.h:154
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
#define AST_CAUSE_FAILURE
Definition: causes.h:149
#define AST_CAUSE_NORMAL_UNSPECIFIED
Definition: causes.h:118
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:153
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:111
#define AST_CAUSE_INTERWORKING
Definition: causes.h:145
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
#define AST_CAUSE_CONGESTION
Definition: causes.h:152

◆ hangup_data_alloc()

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

Definition at line 2461 of file chan_pjsip.c.

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

Referenced by chan_pjsip_hangup().

2462 {
2463  struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
2464 
2465  if (!h_data) {
2466  return NULL;
2467  }
2468 
2469  h_data->cause = cause;
2470  h_data->chan = ast_channel_ref(chan);
2471 
2472  return h_data;
2473 }
static void hangup_data_destroy(void *obj)
Definition: chan_pjsip.c:2454
#define NULL
Definition: resample.c:96
struct ast_channel * chan
Definition: chan_pjsip.c:2451
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970

◆ hangup_data_destroy()

static void hangup_data_destroy ( void *  obj)
static

Definition at line 2454 of file chan_pjsip.c.

References ast_channel_unref, and hangup_data::chan.

Referenced by hangup_data_alloc().

2455 {
2456  struct hangup_data *h_data = obj;
2457 
2458  h_data->chan = ast_channel_unref(h_data->chan);
2459 }
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
struct ast_channel * chan
Definition: chan_pjsip.c:2451

◆ hangup_sip2cause()

static int hangup_sip2cause ( int  cause)
static

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 2860 of file chan_pjsip.c.

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

Referenced by chan_pjsip_incoming_response_update_cause(), and chan_pjsip_session_end().

2861 {
2862  /* Possible values taken from causes.h */
2863 
2864  switch(cause) {
2865  case 401: /* Unauthorized */
2866  return AST_CAUSE_CALL_REJECTED;
2867  case 403: /* Not found */
2868  return AST_CAUSE_CALL_REJECTED;
2869  case 404: /* Not found */
2870  return AST_CAUSE_UNALLOCATED;
2871  case 405: /* Method not allowed */
2872  return AST_CAUSE_INTERWORKING;
2873  case 407: /* Proxy authentication required */
2874  return AST_CAUSE_CALL_REJECTED;
2875  case 408: /* No reaction */
2877  case 409: /* Conflict */
2879  case 410: /* Gone */
2880  return AST_CAUSE_NUMBER_CHANGED;
2881  case 411: /* Length required */
2882  return AST_CAUSE_INTERWORKING;
2883  case 413: /* Request entity too large */
2884  return AST_CAUSE_INTERWORKING;
2885  case 414: /* Request URI too large */
2886  return AST_CAUSE_INTERWORKING;
2887  case 415: /* Unsupported media type */
2888  return AST_CAUSE_INTERWORKING;
2889  case 420: /* Bad extension */
2891  case 480: /* No answer */
2892  return AST_CAUSE_NO_ANSWER;
2893  case 481: /* No answer */
2894  return AST_CAUSE_INTERWORKING;
2895  case 482: /* Loop detected */
2896  return AST_CAUSE_INTERWORKING;
2897  case 483: /* Too many hops */
2898  return AST_CAUSE_NO_ANSWER;
2899  case 484: /* Address incomplete */
2901  case 485: /* Ambiguous */
2902  return AST_CAUSE_UNALLOCATED;
2903  case 486: /* Busy everywhere */
2904  return AST_CAUSE_BUSY;
2905  case 487: /* Request terminated */
2906  return AST_CAUSE_INTERWORKING;
2907  case 488: /* No codecs approved */
2909  case 491: /* Request pending */
2910  return AST_CAUSE_INTERWORKING;
2911  case 493: /* Undecipherable */
2912  return AST_CAUSE_INTERWORKING;
2913  case 500: /* Server internal failure */
2914  return AST_CAUSE_FAILURE;
2915  case 501: /* Call rejected */
2917  case 502:
2919  case 503: /* Service unavailable */
2920  return AST_CAUSE_CONGESTION;
2921  case 504: /* Gateway timeout */
2923  case 505: /* SIP version not supported */
2924  return AST_CAUSE_INTERWORKING;
2925  case 600: /* Busy everywhere */
2926  return AST_CAUSE_USER_BUSY;
2927  case 603: /* Decline */
2928  return AST_CAUSE_CALL_REJECTED;
2929  case 604: /* Does not exist anywhere */
2930  return AST_CAUSE_UNALLOCATED;
2931  case 606: /* Not acceptable */
2933  default:
2934  if (cause < 500 && cause >= 400) {
2935  /* 4xx class error that is unknown - someting wrong with our request */
2936  return AST_CAUSE_INTERWORKING;
2937  } else if (cause < 600 && cause >= 500) {
2938  /* 5xx class error - problem in the remote end */
2939  return AST_CAUSE_CONGESTION;
2940  } else if (cause < 700 && cause >= 600) {
2941  /* 6xx - global errors in the 4xx class */
2942  return AST_CAUSE_INTERWORKING;
2943  }
2944  return AST_CAUSE_NORMAL;
2945  }
2946  /* Never reached */
2947  return 0;
2948 }
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:121
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
#define AST_CAUSE_FACILITY_REJECTED
Definition: causes.h:116
#define AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE
Definition: causes.h:142
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:107
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
#define AST_CAUSE_NORMAL
Definition: causes.h:150
#define AST_CAUSE_FAILURE
Definition: causes.h:149
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:111
#define AST_CAUSE_INTERWORKING
Definition: causes.h:145
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
#define AST_CAUSE_BUSY
Definition: causes.h:148
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
#define AST_CAUSE_CONGESTION
Definition: causes.h:152

◆ indicate()

static int indicate ( void *  data)
static

Definition at line 1333 of file chan_pjsip.c.

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

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

1334 {
1335  pjsip_tx_data *packet = NULL;
1336  struct indicate_data *ind_data = data;
1337  struct ast_sip_session *session = ind_data->session;
1338  int response_code = ind_data->response_code;
1339 
1340  if ((session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
1341  (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
1342  ast_sip_session_send_response(session, packet);
1343  }
1344 
1345  ao2_ref(ind_data, -1);
1346 
1347  return 0;
1348 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1293
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
A structure describing a SIP session.
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.

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

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, rtp_direct_media_data::session, and indicate_data::session.

Referenced by chan_pjsip_indicate().

1310 {
1311  struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
1312 
1313  if (!ind_data) {
1314  return NULL;
1315  }
1316 
1317  ind_data->frame_data = ast_malloc(datalen);
1318  if (!ind_data->frame_data) {
1319  ao2_ref(ind_data, -1);
1320  return NULL;
1321  }
1322 
1323  memcpy(ind_data->frame_data, frame_data, datalen);
1324  ind_data->datalen = datalen;
1325  ind_data->condition = condition;
1326  ind_data->response_code = response_code;
1327  ao2_ref(session, +1);
1328  ind_data->session = session;
1329 
1330  return ind_data;
1331 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1293
static void indicate_data_destroy(void *obj)
Definition: chan_pjsip.c:1300
#define NULL
Definition: resample.c:96
static struct ast_mansession session
void * frame_data
Definition: chan_pjsip.c:1296
size_t datalen
Definition: chan_pjsip.c:1297
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411

◆ indicate_data_destroy()

static void indicate_data_destroy ( void *  obj)
static

Definition at line 1300 of file chan_pjsip.c.

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

Referenced by indicate_data_alloc().

1301 {
1302  struct indicate_data *ind_data = obj;
1303 
1304  ast_free(ind_data->frame_data);
1305  ao2_ref(ind_data->session, -1);
1306 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1293
void * frame_data
Definition: chan_pjsip.c:1296
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_free(a)
Definition: astmm.h:182

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

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

Referenced by chan_pjsip_digit_end().

2206 {
2207  struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
2208  if (!dtmf_data) {
2209  return NULL;
2210  }
2211  ao2_ref(session, +1);
2212  dtmf_data->session = session;
2213  dtmf_data->digit = digit;
2214  dtmf_data->duration = duration;
2215  return dtmf_data;
2216 }
char digit
unsigned int duration
Definition: chan_pjsip.c:2196
#define NULL
Definition: resample.c:96
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void info_dtmf_data_destroy(void *obj)
Definition: chan_pjsip.c:2199
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ast_sip_session * session
Definition: chan_pjsip.c:2194

◆ info_dtmf_data_destroy()

static void info_dtmf_data_destroy ( void *  obj)
static

Definition at line 2199 of file chan_pjsip.c.

References ao2_ref, and info_dtmf_data::session.

Referenced by info_dtmf_data_alloc().

2200 {
2201  struct info_dtmf_data *dtmf_data = obj;
2202  ao2_ref(dtmf_data->session, -1);
2203 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_sip_session * session
Definition: chan_pjsip.c:2194

◆ is_colp_update_allowed()

static int is_colp_update_allowed ( struct ast_sip_session session)
static

Definition at line 1402 of file chan_pjsip.c.

References ast_channel_connected_effective_id(), ast_channel_lock, ast_channel_unlock, ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sip_session::channel, ast_sip_session::endpoint, ast_sip_endpoint::id, ast_party_id::number, ast_sip_endpoint_id_configuration::send_connected_line, ast_sip_endpoint_id_configuration::send_pai, ast_sip_endpoint_id_configuration::send_rpid, ast_sip_endpoint_id_configuration::trust_outbound, and ast_party_number::valid.

Referenced by update_connected_line_information().

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

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

References ast_sip_session::active_media_state, ast_format_cap_iscompatible_format(), AST_FORMAT_CMP_NOT_EQUAL, ast_stream_get_formats(), ast_stream_topology_get_stream(), ast_frame_subclass::format, ast_frame::stream_num, ast_frame::subclass, and ast_sip_session_media_state::topology.

Referenced by chan_pjsip_read_stream().

825 {
826  struct ast_stream_topology *topology = session->active_media_state->topology;
827  struct ast_stream *stream = ast_stream_topology_get_stream(topology, f->stream_num);
828  const struct ast_format_cap *cap = ast_stream_get_formats(stream);
829 
831 }
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
struct ast_frame_subclass subclass
struct ast_sip_session_media_state * active_media_state
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_stream_topology * topology
The media stream topology.
struct ast_format * format

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

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(), ast_channel_tech::capabilities, channel_type, end, endpoints, LOG_ERROR, LOG_WARNING, NULL, OBJ_NODATA, pjsip_channel_cli_register(), refer_callback_module, uid_hold_hash_fn(), uid_hold_sort_fn(), and update_devstate().

Referenced by unload_module().

3305 {
3306  struct ao2_container *endpoints;
3307 
3309  return AST_MODULE_LOAD_DECLINE;
3310  }
3311 
3313 
3315 
3317  ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
3318  goto end;
3319  }
3320 
3322  ast_log(LOG_ERROR, "Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
3323  goto end;
3324  }
3325 
3327  ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI dialplan function\n");
3328  goto end;
3329  }
3330 
3332  ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
3333  goto end;
3334  }
3335 
3337  ast_log(LOG_WARNING, "Unable to register PJSIP_DTMF_MODE dialplan function\n");
3338  goto end;
3339  }
3340 
3342  ast_log(LOG_WARNING, "Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
3343  goto end;
3344  }
3345 
3347  ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
3348  goto end;
3349  }
3350 
3352 
3355 
3358  uid_hold_sort_fn, NULL))) {
3359  ast_log(LOG_ERROR, "Unable to create held channels container\n");
3360  goto end;
3361  }
3362 
3366 
3368  ast_log(LOG_ERROR, "Unable to register PJSIP Channel CLI\n");
3369  goto end;
3370  }
3371 
3372  /* since endpoints are loaded before the channel driver their device
3373  states get set to 'invalid', so they need to be updated */
3374  if ((endpoints = ast_sip_get_endpoints())) {
3376  ao2_ref(endpoints, -1);
3377  }
3378 
3379  return 0;
3380 
3381 end:
3398 
3399  return AST_MODULE_LOAD_DECLINE;
3400 }
static struct ast_custom_function session_refresh_function
Definition: chan_pjsip.c:3289
static struct ast_custom_function media_offer_function
Definition: chan_pjsip.c:3271
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
static struct ast_custom_function dtmf_mode_function
Definition: chan_pjsip.c:3277
static struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Definition: chan_pjsip.c:155
#define LOG_WARNING
Definition: logger.h:274
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:847
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1915
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
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
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 NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
static struct ast_custom_function chan_pjsip_dial_contacts_function
Definition: chan_pjsip.c:3261
static int uid_hold_hash_fn(const void *obj, const int flags)
Definition: chan_pjsip.c:1066
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
Definition: chan_pjsip.c:164
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define ast_log
Definition: astobj2.c:42
static int update_devstate(void *obj, void *arg, int flags)
Definition: chan_pjsip.c:3254
static struct ao2_container * endpoints
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct ast_custom_function moh_passthrough_function
Definition: chan_pjsip.c:3283
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:3315
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
Definition: chan_pjsip.c:143
static const char channel_type[]
Definition: chan_pjsip.c:78
struct ast_format_cap * capabilities
Definition: channel.h:633
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1107
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
Definition: cli_commands.c:448
static struct ast_custom_function chan_pjsip_parse_uri_function
Definition: chan_pjsip.c:3266
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ast_sip_session_supplement call_pickup_supplement
Definition: chan_pjsip.c:3109
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:3331
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
struct ao2_container * ast_sip_get_endpoints(void)
Retrieve any endpoints available to sorcery.
Reject objects with duplicate keys in container.
Definition: astobj2.h:1192
Generic container type.
static struct ast_sip_session_supplement pbx_start_supplement
Definition: chan_pjsip.c:3149
static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
Definition: chan_pjsip.c:1084
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
#define ast_sip_session_register_supplement(supplement)
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
Definition: chan_pjsip.c:486

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

References ast_sip_session_media::locally_held.

Referenced by remote_send_hold_refresh().

1483 {
1484  if (session_media) {
1485  session_media->locally_held = held;
1486  }
1487 }
unsigned int locally_held
Stream is on hold by local side.

◆ on_topology_change_response()

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

Definition at line 1549 of file chan_pjsip.c.

References ast_sip_session::active_media_state, 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(), ast_sip_session::channel, ast_sip_session::pending_media_state, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and ast_sip_session_media_state::topology.

Referenced by send_topology_change_refresh().

1550 {
1551  SCOPE_ENTER(3, "%s: Received response code %d. PT: %s AT: %s\n", ast_sip_session_get_name(session),
1552  rdata->msg_info.msg->line.status.code,
1555 
1556 
1557  if (PJSIP_IS_STATUS_IN_CLASS(rdata->msg_info.msg->line.status.code, 200)) {
1558  /* The topology was changed to something new so give notice to what requested
1559  * it so it queries the channel and updates accordingly.
1560  */
1561  if (session->channel) {
1563  SCOPE_EXIT_RTN_VALUE(0, "%s: Queued topology change frame\n", ast_sip_session_get_name(session));
1564  }
1565  SCOPE_EXIT_RTN_VALUE(0, "%s: No channel? Can't queue topology change frame\n", ast_sip_session_get_name(session));
1566  } else if (300 <= rdata->msg_info.msg->line.status.code) {
1567  /* The topology change failed, so drop the current pending media state */
1569  SCOPE_EXIT_RTN_VALUE(0, "%s: response code > 300. Resetting pending media state\n", ast_sip_session_get_name(session));
1570  }
1571 
1572  SCOPE_EXIT_RTN_VALUE(0, "%s: Nothing to do\n", ast_sip_session_get_name(session));
1573 }
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
struct ast_sip_session_media_state * pending_media_state
struct ast_sip_session_media_state * active_media_state
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
struct ast_channel * channel
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
struct ast_stream_topology * topology
The media stream topology.
void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state)
Reset a media state to a clean state.

◆ pbx_start_incoming_request()

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

Definition at line 3115 of file chan_pjsip.c.

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(), ast_sip_session::channel, LOG_WARNING, SCOPE_ENTER, and SCOPE_EXIT_RTN_VALUE.

3116 {
3117  int res;
3118  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
3119 
3120  /* Check for a to-tag to determine if this is a reinvite */
3121  if (rdata->msg_info.to->tag.slen) {
3122  /* We don't care about reinvites */
3123  SCOPE_EXIT_RTN_VALUE(0, "Reinvite\n");
3124  }
3125 
3126  res = ast_pbx_start(session->channel);
3127 
3128  switch (res) {
3129  case AST_PBX_FAILED:
3130  ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
3132  ast_hangup(session->channel);
3133  break;
3134  case AST_PBX_CALL_LIMIT:
3135  ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
3137  ast_hangup(session->channel);
3138  break;
3139  case AST_PBX_SUCCESS:
3140  default:
3141  break;
3142  }
3143 
3144  ast_debug(3, "Started PBX on new PJSIP channel %s\n", ast_channel_name(session->channel));
3145 
3146  SCOPE_EXIT_RTN_VALUE((res == AST_PBX_SUCCESS) ? 0 : -1, "RC: %d\n", res);
3147 }
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define LOG_WARNING
Definition: logger.h:274
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_channel * channel
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
const char * ast_channel_name(const struct ast_channel *chan)

◆ remote_send_hold()

static int remote_send_hold ( void *  data)
static

Update local hold state to be held.

Definition at line 1500 of file chan_pjsip.c.

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

1501 {
1502  return remote_send_hold_refresh(data, 1);
1503 }
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:1490

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

References ast_sip_session::active_media_state, ao2_ref, ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, AST_VECTOR_CALLBACK_VOID, local_hold_set_state(), and NULL.

Referenced by remote_send_hold(), and remote_send_unhold().

1491 {
1494  ao2_ref(session, -1);
1495 
1496  return 0;
1497 }
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:1482
#define NULL
Definition: resample.c:96
struct ast_sip_session_media_state * active_media_state
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 ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865

◆ remote_send_unhold()

static int remote_send_unhold ( void *  data)
static

Update local hold state to be unheld.

Definition at line 1506 of file chan_pjsip.c.

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

1507 {
1508  return remote_send_hold_refresh(data, 0);
1509 }
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:1490

◆ request()

static int request ( void *  obj)
static

Definition at line 2559 of file chan_pjsip.c.

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, rtp_direct_media_data::session, request_data::session, tmp(), and request_data::topology.

Referenced by _ast_bridge_channel_unlock(), action_add_agi_cmd(), ast_http_body_discard(), ast_http_body_read_status(), ast_http_get_contents(), ast_http_request_close_on_completion(), ast_http_send(), 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_setup(), httpd_process_request(), parse_ewscal_id(), reload(), 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().

2560 {
2561  struct request_data *req_data = obj;
2562  struct ast_sip_session *session = NULL;
2563  char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
2564  struct ast_sip_endpoint *endpoint;
2565 
2567  AST_APP_ARG(endpoint);
2568  AST_APP_ARG(aor);
2569  );
2570  SCOPE_ENTER(1, "%s\n",tmp);
2571 
2572  if (ast_strlen_zero(tmp)) {
2573  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty destination\n");
2575  SCOPE_EXIT_RTN_VALUE(-1, "Empty destination\n");
2576  }
2577 
2578  AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
2579 
2581  /* If a request user has been specified extract it from the endpoint name portion */
2582  if ((endpoint_name = strchr(args.endpoint, '@'))) {
2583  request_user = args.endpoint;
2584  *endpoint_name++ = '\0';
2585  } else {
2586  endpoint_name = args.endpoint;
2587  }
2588 
2589  if (ast_strlen_zero(endpoint_name)) {
2590  if (request_user) {
2591  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2592  request_user);
2593  } else {
2594  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2595  }
2597  SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2598  }
2599  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2600  endpoint_name);
2601  if (!endpoint) {
2602  ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2604  SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2605  }
2606  } else {
2607  /* First try to find an exact endpoint match, for single (user) or multi-domain (user@domain) */
2608  endpoint_name = args.endpoint;
2609  if (ast_strlen_zero(endpoint_name)) {
2610  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2612  SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2613  }
2614  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2615  endpoint_name);
2616  if (!endpoint) {
2617  /* It seems it's not a multi-domain endpoint or single endpoint exact match,
2618  * it's possible that it's a SIP trunk with a specified user (user@trunkname),
2619  * so extract the user before @ sign.
2620  */
2621  endpoint_name = strchr(args.endpoint, '@');
2622  if (!endpoint_name) {
2623  /*
2624  * Couldn't find an '@' so it had to be an endpoint
2625  * name that doesn't exist.
2626  */
2627  ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n",
2628  args.endpoint);
2630  SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2631  }
2632  request_user = args.endpoint;
2633  *endpoint_name++ = '\0';
2634 
2635  if (ast_strlen_zero(endpoint_name)) {
2636  ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2637  request_user);
2639  SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2640  }
2641 
2642  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2643  endpoint_name);
2644  if (!endpoint) {
2645  ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2647  SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2648  }
2649  }
2650  }
2651 
2652  session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user,
2653  req_data->topology);
2654  ao2_ref(endpoint, -1);
2655  if (!session) {
2656  ast_log(LOG_ERROR, "Failed to create outgoing session to endpoint '%s'\n", endpoint_name);
2658  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create session\n");
2659  }
2660 
2661  req_data->session = session;
2662 
2664 }
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.
static int tmp()
Definition: bt_open.c:389
const char * args
#define NULL
Definition: resample.c:96
A structure describing a SIP session.
#define ast_strlen_zero(foo)
Definition: strings.h:52
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
#define ast_log
Definition: astobj2.c:42
static struct ast_mansession session
struct ast_sip_session * session
Definition: chan_pjsip.c:2553
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
unsigned int ast_sip_get_disable_multi_domain(void)
Retrieve the system setting &#39;disable multi domain&#39;.
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
#define LOG_ERROR
Definition: logger.h:285
#define AST_CAUSE_CHANNEL_UNACCEPTABLE
Definition: causes.h:101
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
struct ast_stream_topology * topology
Definition: chan_pjsip.c:2554
const char * dest
Definition: chan_pjsip.c:2555
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

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

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(), rtp_direct_media_data::session, and rtp_direct_media_data::vrtp.

Referenced by chan_pjsip_set_rtp_peer().

380 {
382 
383  if (!cdata) {
384  return NULL;
385  }
386 
387  cdata->chan = ao2_bump(chan);
388  cdata->rtp = ao2_bump(rtp);
389  cdata->vrtp = ao2_bump(vrtp);
390  cdata->cap = ao2_bump((struct ast_format_cap *)cap);
391  cdata->session = ao2_bump(session);
392 
393  return cdata;
394 }
struct ast_rtp_instance * rtp
Definition: chan_pjsip.c:360
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_channel * chan
Definition: chan_pjsip.c:359
struct ast_format_cap * cap
Definition: chan_pjsip.c:362
struct ast_sip_session * session
Definition: chan_pjsip.c:363
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
static void rtp_direct_media_data_destroy(void *data)
Definition: chan_pjsip.c:366
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static int cdata(void *userdata, int state, const char *cdata, size_t len)
struct ast_rtp_instance * vrtp
Definition: chan_pjsip.c:361

◆ rtp_direct_media_data_destroy()

static void rtp_direct_media_data_destroy ( void *  data)
static

Definition at line 366 of file chan_pjsip.c.

References ao2_cleanup, rtp_direct_media_data::cap, cdata(), rtp_direct_media_data::chan, rtp_direct_media_data::rtp, rtp_direct_media_data::session, and rtp_direct_media_data::vrtp.

Referenced by rtp_direct_media_data_create().

367 {
368  struct rtp_direct_media_data *cdata = data;
369 
370  ao2_cleanup(cdata->session);
371  ao2_cleanup(cdata->cap);
372  ao2_cleanup(cdata->vrtp);
373  ao2_cleanup(cdata->rtp);
374  ao2_cleanup(cdata->chan);
375 }
struct ast_rtp_instance * rtp
Definition: chan_pjsip.c:360
struct ast_channel * chan
Definition: chan_pjsip.c:359
struct ast_format_cap * cap
Definition: chan_pjsip.c:362
struct ast_sip_session * session
Definition: chan_pjsip.c:363
static int cdata(void *userdata, int state, const char *cdata, size_t len)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_rtp_instance * vrtp
Definition: chan_pjsip.c:361

◆ 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.

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

Referenced by check_for_rtp_changes().

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 }
struct ast_sip_session_media_state * active_media_state
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:670
Structure which contains read callback information.
int fd
The file descriptor itself.
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ send_direct_media_request()

static int send_direct_media_request ( void *  data)
static

Definition at line 396 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ao2_ref, ast_channel_lock, ast_channel_name(), ast_channel_tech_pvt(), ast_channel_unlock, ast_debug, ast_format_cap_append_from_cap(), ast_format_cap_count(), ast_format_cap_identical(), ast_format_cap_remove_by_type(), AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, AST_MEDIA_TYPE_VIDEO, ast_sip_session_refresh(), rtp_direct_media_data::cap, cdata(), rtp_direct_media_data::chan, check_for_rtp_changes(), ast_sip_session_media_state::default_session, ast_sip_endpoint_media_configuration::direct_media, ast_sip_session::direct_media_cap, direct_media_mitigate_glare(), ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_direct_media_configuration::method, NULL, rtp_direct_media_data::rtp, rtp_direct_media_data::session, ast_sip_channel_pvt::session, and rtp_direct_media_data::vrtp.

Referenced by chan_pjsip_set_rtp_peer().

397 {
398  struct rtp_direct_media_data *cdata = data;
400  struct ast_sip_session *session;
401  int changed = 0;
402  int res = 0;
403 
404  /* XXX In an ideal world each media stream would be direct, but for now preserve behavior
405  * and connect only the default media sessions for audio and video.
406  */
407 
408  /* The channel needs to be locked when checking for RTP changes.
409  * Otherwise, we could end up destroying an underlying RTCP structure
410  * at the same time that the channel thread is attempting to read RTCP
411  */
412  ast_channel_lock(cdata->chan);
413  session = channel->session;
415  changed |= check_for_rtp_changes(
416  cdata->chan, cdata->rtp, session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO], session);
417  }
419  changed |= check_for_rtp_changes(
420  cdata->chan, cdata->vrtp, session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO], session);
421  }
422  ast_channel_unlock(cdata->chan);
423 
424  if (direct_media_mitigate_glare(cdata->session)) {
425  ast_debug(4, "Disregarding setting RTP on %s: mitigating re-INVITE glare\n", ast_channel_name(cdata->chan));
426  ao2_ref(cdata, -1);
427  return 0;
428  }
429 
430  if (cdata->cap && ast_format_cap_count(cdata->cap) &&
434  changed = 1;
435  }
436 
437  if (changed) {
438  ast_debug(4, "RTP changed on %s; initiating direct media update\n", ast_channel_name(cdata->chan));
439  res = ast_sip_session_refresh(cdata->session, NULL, NULL, NULL,
441  }
442 
443  ao2_ref(cdata, -1);
444  return res;
445 }
static int direct_media_mitigate_glare(struct ast_sip_session *session)
Definition: chan_pjsip.c:268
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_sip_endpoint * endpoint
struct ast_rtp_instance * rtp
Definition: chan_pjsip.c:360
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
enum ast_sip_session_refresh_method method
Definition: res_pjsip.h:733
struct ast_sip_session * session
Pointer to session.
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)
Definition: chan_pjsip.c:319
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
Definition: muted.c:95
#define NULL
Definition: resample.c:96
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:766
A structure describing a SIP session.
struct ast_format_cap * direct_media_cap
struct ast_sip_session_media_state * active_media_state
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * chan
Definition: chan_pjsip.c:359
static struct ast_mansession session
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 ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_format_cap * cap
Definition: chan_pjsip.c:362
struct ast_sip_session * session
Definition: chan_pjsip.c:363
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if two capabilities structures are identical.
Definition: format_cap.c:689
static int cdata(void *userdata, int state, const char *cdata, size_t len)
const char * ast_channel_name(const struct ast_channel *chan)
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_rtp_instance * vrtp
Definition: chan_pjsip.c:361

◆ send_topology_change_refresh()

static int send_topology_change_refresh ( void *  data)
static

Definition at line 1575 of file chan_pjsip.c.

References ast_sip_session_get_name(), ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, ast_str_tmp, ast_stream_topology_to_str(), topology_change_refresh_data::media_state, NULL, on_topology_change_response(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, topology_change_refresh_data::session, ast_sip_session_media_state::topology, and topology_change_refresh_data_free().

Referenced by handle_topology_request_change().

1576 {
1578  struct ast_sip_session *session = refresh_data->session;
1579  int ret;
1580  SCOPE_ENTER(3, "%s: %s\n", ast_sip_session_get_name(session),
1581  ast_str_tmp(256, ast_stream_topology_to_str(refresh_data->media_state->topology, &STR_TMP)));
1582 
1583 
1586  refresh_data->media_state = NULL;
1587  topology_change_refresh_data_free(refresh_data);
1588 
1589  SCOPE_EXIT_RTN_VALUE(ret, "%s\n", ast_sip_session_get_name(session));
1590 }
#define NULL
Definition: resample.c:96
A structure describing a SIP session.
static int on_topology_change_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
Definition: chan_pjsip.c:1549
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
static struct ast_mansession session
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.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
struct ast_sip_session_media_state * media_state
Definition: chan_pjsip.c:1513
struct ast_stream_topology * topology
The media stream topology.
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
Definition: chan_pjsip.c:1516
struct ast_sip_session * session
Definition: chan_pjsip.c:1512

◆ sendtext()

static int sendtext ( void *  obj)
static

Definition at line 2744 of file chan_pjsip.c.

References ao2_cleanup, ast_log, AST_MSG_DATA_ATTR_BODY, AST_MSG_DATA_ATTR_CONTENT_TYPE, AST_MSG_DATA_ATTR_FROM, AST_MSG_DATA_ATTR_TO, ast_msg_data_get_attribute(), ast_sip_add_body(), ast_sip_create_request(), ast_sip_send_request(), ast_strlen_zero, ast_sip_body::body_text, ast_sip_session::endpoint, ast_sip_session::inv_session, LOG_ERROR, sendtext_data::msg, NULL, sendtext_data::session, ast_sip_body::subtype, and ast_sip_body::type.

Referenced by chan_pjsip_sendtext_data().

2745 {
2746  struct sendtext_data *data = obj;
2747  pjsip_tx_data *tdata;
2748  const char *body_text = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_BODY);
2749  const char *content_type = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_CONTENT_TYPE);
2750  char *sep;
2751  struct ast_sip_body body = {
2752  .type = "text",
2753  .subtype = "plain",
2754  .body_text = body_text,
2755  };
2756 
2757  if (!ast_strlen_zero(content_type)) {
2758  sep = strchr(content_type, '/');
2759  if (sep) {
2760  *sep = '\0';
2761  body.type = content_type;
2762  body.subtype = ++sep;
2763  }
2764  }
2765 
2766  if (data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2767  ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2768  data->session->inv_session->cause,
2769  pjsip_get_status_text(data->session->inv_session->cause)->ptr);
2770  } else {
2771  pjsip_from_hdr *hdr;
2772  pjsip_name_addr *name_addr;
2773  const char *from = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_FROM);
2774  const char *to = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_TO);
2775  int invalidate_tdata = 0;
2776 
2777  ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
2778  ast_sip_add_body(tdata, &body);
2779 
2780  /*
2781  * If we have a 'from' in the msg, set the display name in the From
2782  * header to it.
2783  */
2784  if (!ast_strlen_zero(from)) {
2785  hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
2786  name_addr = (pjsip_name_addr *) hdr->uri;
2787  pj_strdup2(tdata->pool, &name_addr->display, from);
2788  invalidate_tdata = 1;
2789  }
2790 
2791  /*
2792  * If we have a 'to' in the msg, set the display name in the To
2793  * header to it.
2794  */
2795  if (!ast_strlen_zero(to)) {
2796  hdr = PJSIP_MSG_TO_HDR(tdata->msg);
2797  name_addr = (pjsip_name_addr *) hdr->uri;
2798  pj_strdup2(tdata->pool, &name_addr->display, to);
2799  invalidate_tdata = 1;
2800  }
2801 
2802  if (invalidate_tdata) {
2803  pjsip_tx_data_invalidate_msg(tdata);
2804  }
2805 
2806  ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
2807  }
2808 
2809  ao2_cleanup(data);
2810 
2811  return 0;
2812 }
const char * body_text
Definition: res_pjsip.h:2033
struct ast_sip_endpoint * endpoint
struct ast_sip_session * session
Definition: chan_pjsip.c:2712
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending a SIP request.
Definition: res_pjsip.c:5034
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
struct ast_msg_data * msg
Definition: chan_pjsip.c:2713
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
Definition: res_pjsip.c:5091
const char * type
Definition: res_pjsip.h:2029
#define LOG_ERROR
Definition: logger.h:285
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
Definition: message.c:1533
const char * subtype
Definition: res_pjsip.h:2031
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
SIP body description.
Definition: res_pjsip.h:2027
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
Definition: res_pjsip.c:4490

◆ sendtext_data_create()

static struct sendtext_data* sendtext_data_create ( struct ast_channel chan,
struct ast_msg_data msg 
)
static

Definition at line 2723 of file chan_pjsip.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_channel_tech_pvt(), ast_msg_data_dup(), sendtext_data::msg, NULL, sendtext_data_destroy(), ast_sip_channel_pvt::session, and sendtext_data::session.

Referenced by chan_pjsip_sendtext_data().

2725 {
2727  struct sendtext_data *data = ao2_alloc(sizeof(*data), sendtext_data_destroy);
2728 
2729  if (!data) {
2730  return NULL;
2731  }
2732 
2733  data->msg = ast_msg_data_dup(msg);
2734  if (!data->msg) {
2735  ao2_cleanup(data);
2736  return NULL;
2737  }
2738  data->session = channel->session;
2739  ao2_ref(data->session, +1);
2740 
2741  return data;
2742 }
struct ast_msg_data * ast_msg_data_dup(struct ast_msg_data *msg)
Clone an ast_msg_data structure.
Definition: message.c:1495
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_sip_session * session
Definition: chan_pjsip.c:2712
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Definition: muted.c:95
#define NULL
Definition: resample.c:96
static void sendtext_data_destroy(void *obj)
Definition: chan_pjsip.c:2716
struct ast_msg_data * msg
Definition: chan_pjsip.c:2713
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ sendtext_data_destroy()

static void sendtext_data_destroy ( void *  obj)
static

Definition at line 2716 of file chan_pjsip.c.

References ao2_cleanup, ast_free, sendtext_data::msg, and sendtext_data::session.

Referenced by sendtext_data_create().

2717 {
2718  struct sendtext_data *data = obj;
2719  ao2_cleanup(data->session);
2720  ast_free(data->msg);
2721 }
struct ast_sip_session * session
Definition: chan_pjsip.c:2712
struct ast_msg_data * msg
Definition: chan_pjsip.c:2713
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ set_channel_on_rtp_instance()

static void set_channel_on_rtp_instance ( const struct ast_sip_session session,
const char *  channel_id 
)
static

Definition at line 494 of file chan_pjsip.c.

References ast_sip_session::active_media_state, ast_rtp_instance_set_channel_id(), AST_VECTOR_GET, AST_VECTOR_SIZE, and ast_sip_session_media::rtp.

Referenced by call(), chan_pjsip_fixup(), chan_pjsip_new(), and clear_session_and_channel().

496 {
497  int i;
498 
499  for (i = 0; i < AST_VECTOR_SIZE(&session->active_media_state->sessions); ++i) {
500  struct ast_sip_session_media *session_media;
501 
502  session_media = AST_VECTOR_GET(&session->active_media_state->sessions, i);
503  if (!session_media || !session_media->rtp) {
504  continue;
505  }
506 
507  ast_rtp_instance_set_channel_id(session_media->rtp, channel_id);
508  }
509 }
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
Definition: rtp_engine.c:553
struct ast_sip_session_media_state * active_media_state
A structure containing SIP session media information.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
struct ast_rtp_instance * rtp
RTP instance itself.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ set_sipdomain_variable()

static void set_sipdomain_variable ( struct ast_sip_session session)
static

Definition at line 2994 of file chan_pjsip.c.

References ast_alloca, ast_copy_pj_str(), ast_sip_session::channel, pbx_builtin_setvar_helper(), and ast_sip_session::request_uri.

Referenced by chan_pjsip_incoming_request().

2995 {
2996  pjsip_sip_uri *sip_ruri = pjsip_uri_get_uri(session->request_uri);
2997  size_t size = pj_strlen(&sip_ruri->host) + 1;
2998  char *domain = ast_alloca(size);
2999 
3000  ast_copy_pj_str(domain, &sip_ruri->host, size);
3001 
3002  pbx_builtin_setvar_helper(session->channel, "SIPDOMAIN", domain);
3003  return;
3004 }
pjsip_uri * request_uri
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
Domain data structure.
Definition: sip.h:888
struct ast_channel * channel
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
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...

◆ topology_change_refresh_data_alloc()

static struct topology_change_refresh_data* topology_change_refresh_data_alloc ( struct ast_sip_session session,
const struct ast_stream_topology topology 
)
static

Definition at line 1524 of file chan_pjsip.c.

References ao2_bump, ast_calloc, ast_sip_session_media_state_alloc(), ast_stream_topology_clone(), topology_change_refresh_data::media_state, NULL, topology_change_refresh_data::session, ast_sip_session_media_state::topology, and topology_change_refresh_data_free().

Referenced by handle_topology_request_change().

1526 {
1528 
1529  refresh_data = ast_calloc(1, sizeof(*refresh_data));
1530  if (!refresh_data) {
1531  return NULL;
1532  }
1533 
1534  refresh_data->session = ao2_bump(session);
1536  if (!refresh_data->media_state) {
1537  topology_change_refresh_data_free(refresh_data);
1538  return NULL;
1539  }
1540  refresh_data->media_state->topology = ast_stream_topology_clone(topology);
1541  if (!refresh_data->media_state->topology) {
1542  topology_change_refresh_data_free(refresh_data);
1543  return NULL;
1544  }
1545 
1546  return refresh_data;
1547 }
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
struct ast_sip_session_media_state * media_state
Definition: chan_pjsip.c:1513
struct ast_stream_topology * topology
The media stream topology.
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
Definition: chan_pjsip.c:1516
struct ast_sip_session * session
Definition: chan_pjsip.c:1512

◆ topology_change_refresh_data_free()

static void topology_change_refresh_data_free ( struct topology_change_refresh_data refresh_data)
static

Definition at line 1516 of file chan_pjsip.c.

References ao2_cleanup, ast_free, ast_sip_session_media_state_free(), topology_change_refresh_data::media_state, and topology_change_refresh_data::session.

Referenced by handle_topology_request_change(), send_topology_change_refresh(), and topology_change_refresh_data_alloc().

1517 {
1518  ao2_cleanup(refresh_data->session);
1519 
1521  ast_free(refresh_data);
1522 }
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.
#define ast_free(a)
Definition: astmm.h:182
struct ast_sip_session_media_state * media_state
Definition: chan_pjsip.c:1513
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_sip_session * session
Definition: chan_pjsip.c:1512

◆ transfer()

static int transfer ( void *  data)
static

Definition at line 2096 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_sip_endpoint::aors, ast_log, ast_sip_get_sorcery(), ast_sip_location_retrieve_contact_from_aor_list(), ast_sorcery_retrieve_by_id(), AST_STATE_RING, ast_strlen_zero, ast_sip_session::channel, ast_sip_session::inv_session, LOG_ERROR, NULL, transfer_data::session, transfer_data::target, transfer_redirect(), transfer_refer(), and ast_sip_contact::uri.

Referenced by chan_pjsip_transfer().

2097 {
2098  struct transfer_data *trnf_data = data;
2099  struct ast_sip_endpoint *endpoint = NULL;
2100  struct ast_sip_contact *contact = NULL;
2101  const char *target = trnf_data->target;
2102 
2103  if (trnf_data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2104  ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2105  trnf_data->session->inv_session->cause,
2106  pjsip_get_status_text(trnf_data->session->inv_session->cause)->ptr);
2107  } else {
2108  /* See if we have an endpoint; if so, use its contact */
2109  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", target);
2110  if (endpoint) {
2112  if (contact && !ast_strlen_zero(contact->uri)) {
2113  target = contact->uri;
2114  }
2115  }
2116 
2117  if (ast_channel_state(trnf_data->session->channel) == AST_STATE_RING) {
2118  transfer_redirect(trnf_data->session, target);
2119  } else {
2120  transfer_refer(trnf_data->session, target);
2121  }
2122  }
2123 
2124  ao2_ref(trnf_data, -1);
2125  ao2_cleanup(endpoint);
2126  ao2_cleanup(contact);
2127  return 0;
2128 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1846
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
#define ast_strlen_zero(foo)
Definition: strings.h:52
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
#define ast_log
Definition: astobj2.c:42
static void transfer_refer(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:2044
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
struct ast_sip_contact * ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list)
Retrieve the first bound contact from a list of AORs.
Definition: location.c:304
#define LOG_ERROR
Definition: logger.h:285
Contact associated with an address of record.
Definition: res_pjsip.h:281
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const ast_string_field aors
Definition: res_pjsip.h:821
const ast_string_field uri
Definition: res_pjsip.h:303
static void transfer_redirect(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1877

◆ transfer_data_alloc()

static struct transfer_data* transfer_data_alloc ( struct ast_sip_session session,
const char *  target 
)
static

Definition at line 1858 of file chan_pjsip.c.

References ao2_alloc, ao2_ref, ast_strdup, NULL, rtp_direct_media_data::session, transfer_data::session, transfer_data::target, and transfer_data_destroy().

Referenced by chan_pjsip_transfer().

1859 {
1860  struct transfer_data *trnf_data = ao2_alloc(sizeof(*trnf_data), transfer_data_destroy);
1861 
1862  if (!trnf_data) {
1863  return NULL;
1864  }
1865 
1866  if (!(trnf_data->target = ast_strdup(target))) {
1867  ao2_ref(trnf_data, -1);
1868  return NULL;
1869  }
1870 
1871  ao2_ref(session, +1);
1872  trnf_data->session = session;
1873 
1874  return trnf_data;
1875 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1846
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static void transfer_data_destroy(void *obj)
Definition: chan_pjsip.c:1850
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411

◆ transfer_data_destroy()

static void transfer_data_destroy ( void *  obj)
static

Definition at line 1850 of file chan_pjsip.c.

References ao2_cleanup, ast_free, transfer_data::session, and transfer_data::target.

Referenced by transfer_data_alloc().

1851 {
1852  struct transfer_data *trnf_data = obj;
1853 
1854  ast_free(trnf_data->target);
1855  ao2_cleanup(trnf_data->session);
1856 }
struct ast_sip_session * session
Definition: chan_pjsip.c:1846
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ transfer_redirect()

static void transfer_redirect ( struct ast_sip_session session,
const char *  target 
)
static

Definition at line 1877 of file chan_pjsip.c.

References ast_channel_name(), AST_CONTROL_TRANSFER, ast_log, ast_queue_control_data(), ast_sip_session_send_response(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, ast_sip_session::channel, ast_sip_session::inv_session, LOG_WARNING, NULL, and tmp().

Referenced by transfer().

1878 {
1879  pjsip_tx_data *packet;
1881  pjsip_contact_hdr *contact;
1882  pj_str_t tmp;
1883 
1884  if (pjsip_inv_end_session(session->inv_session, 302, NULL, &packet) != PJ_SUCCESS
1885  || !packet) {
1886  ast_log(LOG_WARNING, "Failed to redirect PJSIP session for channel %s\n",
1887  ast_channel_name(session->channel));
1888  message = AST_TRANSFER_FAILED;
1889  ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
1890 
1891  return;
1892  }
1893 
1894  if (!(contact = pjsip_msg_find_hdr(packet->msg, PJSIP_H_CONTACT, NULL))) {
1895  contact = pjsip_contact_hdr_create(packet->pool);
1896  }
1897 
1898  pj_strdup2_with_null(packet->pool, &tmp, target);
1899  if (!(contact->uri = pjsip_parse_uri(packet->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR))) {
1900  ast_log(LOG_WARNING, "Failed to parse destination URI '%s' for channel %s\n",
1901  target, ast_channel_name(session->channel));
1902  message = AST_TRANSFER_FAILED;
1903  ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
1904  pjsip_tx_data_dec_ref(packet);
1905 
1906  return;
1907  }
1908  pjsip_msg_add_hdr(packet->msg, (pjsip_hdr *) contact);
1909 
1910  ast_sip_session_send_response(session, packet);
1911  ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
1912 }
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
ast_control_transfer
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
#define ast_log
Definition: astobj2.c:42
struct ast_channel * channel
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
const char * ast_channel_name(const struct ast_channel *chan)
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:1238

◆ transfer_refer()

static void transfer_refer ( struct ast_sip_session session,
const char *  target 
)
static

Definition at line 2044 of file chan_pjsip.c.

References ao2_ref, AST_CONTROL_TRANSFER, ast_copy_pj_str(), ast_queue_control_data(), ast_sip_add_header(), ast_strlen_zero, AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, rtp_direct_media_data::chan, ast_sip_session::channel, ast_sip_session::inv_session, NULL, pbx_builtin_getvar_helper(), refer_callback_module, sub, tmp(), and xfer_client_on_evsub_state().

Referenced by transfer().

2045 {
2046  pjsip_evsub *sub;
2048  pj_str_t tmp;
2049  pjsip_tx_data *packet;
2050  const char *ref_by_val;
2051  char local_info[pj_strlen(&session->inv_session->dlg->local.info_str) + 1];
2052  struct pjsip_evsub_user xfer_cb;
2053  struct ast_channel *chan = session->channel;
2054 
2055  pj_bzero(&xfer_cb, sizeof(xfer_cb));
2056  xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
2057 
2058  if (pjsip_xfer_create_uac(session->inv_session->dlg, &xfer_cb, &sub) != PJ_SUCCESS) {
2059  message = AST_TRANSFER_FAILED;
2060  ast_queue_control_data(chan, AST_CONTROL_TRANSFER, &message, sizeof(message));
2061 
2062  return;
2063  }
2064 
2065  /* refer_callback_module requires a reference to chan
2066  * which will be released in xfer_client_on_evsub_state()
2067  * when the implicit REFER subscription terminates */
2068  pjsip_evsub_set_mod_data(sub, refer_callback_module.id, chan);
2069  ao2_ref(chan, +1);
2070 
2071  if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {
2072  goto failure;
2073  }
2074 
2075  ref_by_val = pbx_builtin_getvar_helper(chan, "SIPREFERREDBYHDR");
2076  if (!ast_strlen_zero(ref_by_val)) {
2077  ast_sip_add_header(packet, "Referred-By", ref_by_val);
2078  } else {
2079  ast_copy_pj_str(local_info, &session->inv_session->dlg->local.info_str, sizeof(local_info));
2080  ast_sip_add_header(packet, "Referred-By", local_info);
2081  }
2082 
2083  if (pjsip_xfer_send_request(sub, packet) == PJ_SUCCESS) {
2084  return;
2085  }
2086 
2087 failure:
2088  message = AST_TRANSFER_FAILED;
2089  ast_queue_control_data(chan, AST_CONTROL_TRANSFER, &message, sizeof(message));
2090  pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2091  pjsip_evsub_terminate(sub, PJ_FALSE);
2092 
2093  ao2_ref(chan, -1);
2094 }
Main Channel structure associated with a channel.
static int tmp()
Definition: bt_open.c:389
ast_control_transfer
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1915
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
Definition: res_pjsip.c:5063
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
static void xfer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
Callback function to report status of implicit REFER-NOTIFY subscription.
Definition: chan_pjsip.c:1927
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:1238
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ transmit_info_dtmf()

static int transmit_info_dtmf ( void *  data)
static

Definition at line 2218 of file chan_pjsip.c.

References ao2_cleanup, ast_free_ptr(), ast_log, ast_sip_add_body(), ast_sip_create_request(), ast_sip_session_send_request(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_sip_body::body_text, ast_sip_session::endpoint, ast_sip_session::inv_session, LOG_ERROR, NULL, RAII_VAR, and ast_sip_body::type.

Referenced by chan_pjsip_digit_end().

2219 {
2220  RAII_VAR(struct info_dtmf_data *, dtmf_data, data, ao2_cleanup);
2221 
2222  struct ast_sip_session *session = dtmf_data->session;
2223  struct pjsip_tx_data *tdata;
2224 
2225  RAII_VAR(struct ast_str *, body_text, NULL, ast_free_ptr);
2226 
2227  struct ast_sip_body body = {
2228  .type = "application",
2229  .subtype = "dtmf-relay",
2230  };
2231 
2232  if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2233  ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2234  session->inv_session->cause,
2235  pjsip_get_status_text(session->inv_session->cause)->ptr);
2236  return -1;
2237  }
2238 
2239  if (!(body_text = ast_str_create(32))) {
2240  ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
2241  return -1;
2242  }
2243  ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
2244 
2246 
2247  if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
2248  ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
2249  return -1;
2250  }
2251  if (ast_sip_add_body(tdata, &body)) {
2252  ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
2253  pjsip_tx_data_dec_ref(tdata);
2254  return -1;
2255  }
2256  ast_sip_session_send_request(session, tdata);
2257 
2258  return 0;
2259 }
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
const char * body_text
Definition: res_pjsip.h:2033
struct ast_sip_endpoint * endpoint
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define NULL
Definition: resample.c:96
const char * data
struct pjsip_inv_session * inv_session
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
A structure describing a SIP session.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
Definition: res_pjsip.c:5091
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
const char * type
Definition: res_pjsip.h:2029
static struct ast_mansession session
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
SIP body description.
Definition: res_pjsip.h:2027
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
Definition: res_pjsip.c:4490

◆ transmit_info_with_vidupdate()

static int transmit_info_with_vidupdate ( void *  data)
static

Send SIP INFO with video update request.

Definition at line 1351 of file chan_pjsip.c.

References ao2_cleanup, ast_log, ast_sip_add_body(), ast_sip_create_request(), ast_sip_session_send_request(), ast_sip_session::endpoint, ast_sip_session::inv_session, LOG_ERROR, NULL, RAII_VAR, and ast_sip_body::type.

Referenced by chan_pjsip_indicate().

1352 {
1353  const char * xml =
1354  "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
1355  " <media_control>\r\n"
1356  " <vc_primitive>\r\n"
1357  " <to_encoder>\r\n"
1358  " <picture_fast_update/>\r\n"
1359  " </to_encoder>\r\n"
1360  " </vc_primitive>\r\n"
1361  " </media_control>\r\n";
1362 
1363  const struct ast_sip_body body = {
1364  .type = "application",
1365  .subtype = "media_control+xml",
1366  .body_text = xml
1367  };
1368 
1369  RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
1370  struct pjsip_tx_data *tdata;
1371 
1372  if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1373  ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1374  session->inv_session->cause,
1375  pjsip_get_status_text(session->inv_session->cause)->ptr);
1376  return -1;
1377  }
1378 
1379  if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
1380  ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
1381  return -1;
1382  }
1383  if (ast_sip_add_body(tdata, &body)) {
1384  ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
1385  return -1;
1386  }
1388 
1389  return 0;
1390 }
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
#define NULL
Definition: resample.c:96
A structure describing a SIP session.
#define ast_log
Definition: astobj2.c:42
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
Definition: res_pjsip.c:5091
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
const char * type
Definition: res_pjsip.h:2029
static struct ast_mansession session
#define LOG_ERROR
Definition: logger.h:285
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
SIP body description.
Definition: res_pjsip.h:2027
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
Definition: res_pjsip.c:4490

◆ transport_info_destroy()

static void transport_info_destroy ( void *  obj)
static

Destructor function for transport_info_data.

Definition at line 253 of file chan_pjsip.c.

References ast_free.

254 {
255  struct transport_info_data *data = obj;
256  ast_free(data);
257 }
Transport information stored in transport_info datastore.
Definition: chan_pjsip.h:30
#define ast_free(a)
Definition: astmm.h:182

◆ uid_hold_hash_fn()

static int uid_hold_hash_fn ( const void *  obj,
const int  flags 
)
static

AO2 hash function for on hold UIDs

Definition at line 1066 of file chan_pjsip.c.

References ast_assert, ast_str_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by load_module().

1067 {
1068  const char *key = obj;
1069 
1070  switch (flags & OBJ_SEARCH_MASK) {
1071  case OBJ_SEARCH_KEY:
1072  break;
1073  case OBJ_SEARCH_OBJECT:
1074  break;
1075  default:
1076  /* Hash can only work on something with a full key. */
1077  ast_assert(0);
1078  return 0;
1079  }
1080  return ast_str_hash(key);
1081 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ast_assert(a)
Definition: utils.h:695
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ uid_hold_sort_fn()

static int uid_hold_sort_fn ( const void *  obj_left,
const void *  obj_right,
const int  flags 
)
static

AO2 sort function for on hold UIDs

Definition at line 1084 of file chan_pjsip.c.

References ast_assert, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by load_module().

1085 {
1086  const char *left = obj_left;
1087  const char *right = obj_right;
1088  int cmp;
1089 
1090  switch (flags & OBJ_SEARCH_MASK) {
1091  case OBJ_SEARCH_OBJECT:
1092  case OBJ_SEARCH_KEY:
1093  cmp = strcmp(left, right);
1094  break;
1096  cmp = strncmp(left, right, strlen(right));
1097  break;
1098  default:
1099  /* Sort can only work on something with a full or partial key. */
1100  ast_assert(0);
1101  cmp = 0;
1102  break;
1103  }
1104  return cmp;
1105 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ast_assert(a)
Definition: utils.h:695
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1120
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076

◆ unload_module()

static int unload_module ( void  )
static

Unload the PJSIP channel from Asterisk.

Definition at line 3403 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_channel_unregister(), ast_custom_function_unregister(), AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_rtp_glue_unregister(), ast_sip_session_unregister_supplement(), ast_sip_unregister_service(), ASTERISK_GPL_KEY, ast_channel_tech::capabilities, load_module(), NULL, pjsip_channel_cli_unregister(), and refer_callback_module.

3404 {
3407 
3409 
3415 
3417 
3424 
3428 
3429  return 0;
3430 }
static struct ast_custom_function session_refresh_function
Definition: chan_pjsip.c:3289
static struct ast_custom_function media_offer_function
Definition: chan_pjsip.c:3271
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
static struct ast_custom_function dtmf_mode_function
Definition: chan_pjsip.c:3277
static struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Definition: chan_pjsip.c:155
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1915
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 NULL
Definition: resample.c:96
static struct ast_custom_function chan_pjsip_dial_contacts_function
Definition: chan_pjsip.c:3261
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
Definition: chan_pjsip.c:164
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
void pjsip_channel_cli_unregister(void)
Unregisters the channel cli commands.
Definition: cli_commands.c:484
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct ast_custom_function moh_passthrough_function
Definition: chan_pjsip.c:3283
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
Definition: chan_pjsip.c:143
struct ast_format_cap * capabilities
Definition: channel.h:633
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1107
static struct ast_custom_function chan_pjsip_parse_uri_function
Definition: chan_pjsip.c:3266
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ast_sip_session_supplement call_pickup_supplement
Definition: chan_pjsip.c:3109
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:3331
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
static struct ast_sip_session_supplement pbx_start_supplement
Definition: chan_pjsip.c:3149
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
Definition: chan_pjsip.c:486

◆ update_connected_line_information()

static int update_connected_line_information ( void *  data)
static

Update connected line information.

Definition at line 1429 of file chan_pjsip.c.

References ao2_ref, ast_log, ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, AST_SIP_SESSION_REFRESH_METHOD_UPDATE, ast_sip_session_send_response(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_sip_session::channel, ast_sip_session::endpoint, ast_sip_endpoint::id, ast_sip_endpoint::inband_progress, ast_sip_session::inv_session, is_colp_update_allowed(), LOG_ERROR, method, NULL, ast_sip_endpoint_id_configuration::refresh_method, and ast_sip_endpoint_id_configuration::rpid_immediate.

Referenced by chan_pjsip_indicate().

1430 {
1431  struct ast_sip_session *session = data;
1432 
1433  if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1434  ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1435  session->inv_session->cause,
1436  pjsip_get_status_text(session->inv_session->cause)->ptr);
1437  ao2_ref(session, -1);
1438  return -1;
1439  }
1440 
1441  if (ast_channel_state(session->channel) == AST_STATE_UP
1442  || session->inv_session->role == PJSIP_ROLE_UAC) {
1443  if (is_colp_update_allowed(session)) {
1445  int generate_new_sdp;
1446 
1447  method = session->endpoint->id.refresh_method;
1448  if (session->inv_session->options & PJSIP_INV_SUPPORT_UPDATE) {
1450  }
1451 
1452  /* Only the INVITE method actually needs SDP, UPDATE can do without */
1453  generate_new_sdp = (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE);
1454 
1455  ast_sip_session_refresh(session, NULL, NULL, NULL, method, generate_new_sdp, NULL);
1456  }
1457  } else if (session->endpoint->id.rpid_immediate
1458  && session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED
1459  && is_colp_update_allowed(session)) {
1460  int response_code = 0;
1461 
1462  if (ast_channel_state(session->channel) == AST_STATE_RING) {
1463  response_code = !session->endpoint->inband_progress ? 180 : 183;
1464  } else if (ast_channel_state(session->channel) == AST_STATE_RINGING) {
1465  response_code = 183;
1466  }
1467 
1468  if (response_code) {
1469  struct pjsip_tx_data *packet = NULL;
1470 
1471  if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
1472  ast_sip_session_send_response(session, packet);
1473  }
1474  }
1475  }
1476 
1477  ao2_ref(session, -1);
1478  return 0;
1479 }
struct ast_sip_endpoint * endpoint
static int is_colp_update_allowed(struct ast_sip_session *session)
Definition: chan_pjsip.c:1402
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
A structure describing a SIP session.
unsigned int inband_progress
Definition: res_pjsip.h:863
#define ast_log
Definition: astobj2.c:42
static struct ast_mansession session
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 ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
const char * method
Definition: res_pjsip.c:4335
enum ast_sip_session_refresh_method refresh_method
Definition: res_pjsip.h:647
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
struct ast_sip_endpoint_id_configuration id
Definition: res_pjsip.h:847
#define LOG_ERROR
Definition: logger.h:285
ast_sip_session_refresh_method
Definition: res_pjsip.h:484

◆ update_devstate()

static int update_devstate ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 3254 of file chan_pjsip.c.

References AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), and ast_sorcery_object_get_id().

Referenced by load_module().

3255 {
3257  "PJSIP/%s", ast_sorcery_object_get_id(obj));
3258  return 0;
3259 }
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
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312

◆ update_initial_connected_line()

static void update_initial_connected_line ( struct ast_sip_session session)
static

Definition at line 2333 of file chan_pjsip.c.

References ast_channel_caller(), ast_channel_lock, ast_channel_queue_connected_line_update(), ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_party_connected_line_init(), ast_party_id_copy(), ast_sip_session::channel, ast_sip_session::id, ast_party_caller::id, ast_party_connected_line::id, ast_party_id::name, NULL, ast_party_id::number, ast_party_connected_line::source, ast_party_name::valid, and ast_party_number::valid.

Referenced by call().

2334 {
2336 
2337  /*
2338  * Use the channel CALLERID() as the initial connected line data.
2339  * The core or a predial handler may have supplied missing values
2340  * from the session->endpoint->id.self about who we are calling.
2341  */
2342  ast_channel_lock(session->channel);
2343  ast_party_id_copy(&session->id, &ast_channel_caller(session->channel)->id);
2344  ast_channel_unlock(session->channel);
2345 
2346  /* Supply initial connected line information if available. */
2347  if (!session->id.number.valid && !session->id.name.valid) {
2348  return;
2349  }
2350 
2352  connected.id = session->id;
2354 
2356 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
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:1765
#define NULL
Definition: resample.c:96
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9202
struct ast_channel * channel
Connected Line/Party information.
Definition: channel.h:457
#define ast_channel_unlock(chan)
Definition: channel.h:2946
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
char connected
Definition: eagi_proxy.c:82
struct ast_party_id id
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ xfer_client_on_evsub_state()

static void xfer_client_on_evsub_state ( pjsip_evsub *  sub,
pjsip_event *  event 
)
static

Callback function to report status of implicit REFER-NOTIFY subscription.

This function will be called on any state change in the REFER-NOTIFY subscription. Its primary purpose is to report SUCCESS/FAILURE of a transfer initiated via transfer_refer as well as to terminate the subscription, if necessary.

Definition at line 1927 of file chan_pjsip.c.

References ao2_ref, ast_channel_name(), AST_CONTROL_TRANSFER, ast_debug, ast_queue_control_data(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, rtp_direct_media_data::chan, NULL, refer_callback_module, and status.

Referenced by transfer_refer().

1928 {
1929  struct ast_channel *chan;
1931  int res = 0;
1932 
1933  if (!event) {
1934  return;
1935  }
1936 
1937  chan = pjsip_evsub_get_mod_data(sub, refer_callback_module.id);
1938  if (!chan) {
1939  return;
1940  }
1941 
1942  if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
1943  /* Check if subscription is suppressed and terminate and send completion code, if so. */
1944  pjsip_rx_data *rdata;
1945  pjsip_generic_string_hdr *refer_sub;
1946  const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
1947 
1948  ast_debug(3, "Transfer accepted on channel %s\n", ast_channel_name(chan));
1949 
1950  /* Check if response message */
1951  if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1952  rdata = event->body.tsx_state.src.rdata;
1953 
1954  /* Find Refer-Sub header */
1955  refer_sub = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &REFER_SUB, NULL);
1956 
1957  /* Check if subscription is suppressed. If it is, the far end will not terminate it,
1958  * and the subscription will remain active until it times out. Terminating it here
1959  * eliminates the unnecessary timeout.
1960  */
1961  if (refer_sub && !pj_stricmp2(&refer_sub->hvalue, "false")) {
1962  /* Since no subscription is desired, assume that call has been transferred successfully. */
1963  /* Channel reference will be released at end of function */
1964  /* Terminate subscription. */
1965  pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
1966  pjsip_evsub_terminate(sub, PJ_TRUE);
1967  res = -1;
1968  }
1969  }
1970  } else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
1971  pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
1972  /* Check for NOTIFY complete or error. */
1973  pjsip_msg *msg;
1974  pjsip_msg_body *body;
1975  pjsip_status_line status_line = { .code = 0 };
1976  pj_bool_t is_last;
1977  pj_status_t status;
1978 
1979  if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1980  pjsip_rx_data *rdata;
1981 
1982  rdata = event->body.tsx_state.src.rdata;
1983  msg = rdata->msg_info.msg;
1984 
1985  if (msg->type == PJSIP_REQUEST_MSG) {
1986  if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
1987  body = msg->body;
1988  if (body && !pj_stricmp2(&body->content_type.type, "message")
1989  && !pj_stricmp2(&body->content_type.subtype, "sipfrag")) {
1990  pjsip_parse_status_line((char *)body->data, body->len, &status_line);
1991  }
1992  }
1993  } else {
1994  status_line.code = msg->line.status.code;
1995  status_line.reason = msg->line.status.reason;
1996  }
1997  } else {
1998  status_line.code = 500;
1999  status_line.reason = *pjsip_get_status_text(500);
2000  }
2001 
2002  is_last = (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED);
2003  /* If the status code is >= 200, the subscription is finished. */
2004  if (status_line.code >= 200 || is_last) {
2005  res = -1;
2006 
2007  /* If the subscription has terminated, return AST_TRANSFER_SUCCESS for 2XX.
2008  * Return AST_TRANSFER_FAILED for any code < 200.
2009  * Otherwise, return the status code.
2010  * The subscription should not terminate for any code < 200,
2011  * but if it does, that constitutes a failure. */
2012  if (status_line.code < 200) {
2013  message = AST_TRANSFER_FAILED;
2014  } else if (status_line.code >= 300) {
2015  message = status_line.code;
2016  }
2017 
2018  /* If subscription not terminated and subscription is finished (status code >= 200)
2019  * terminate it */
2020  if (!is_last) {
2021  pjsip_tx_data *tdata;
2022 
2023  status = pjsip_evsub_initiate(sub, pjsip_get_subscribe_method(), 0, &tdata);
2024  if (status == PJ_SUCCESS) {
2025  pjsip_evsub_send_request(sub, tdata);
2026  }
2027  }
2028  /* Finished. Remove session from subscription */
2029  pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2030  ast_debug(3, "Transfer channel %s completed: %d %.*s (%s)\n",
2031  ast_channel_name(chan),
2032  status_line.code,
2033  (int)status_line.reason.slen, status_line.reason.ptr,
2034  (message == AST_TRANSFER_SUCCESS) ? "Success" : "Failure");
2035  }
2036  }
2037 
2038  if (res) {
2039  ast_queue_control_data(chan, AST_CONTROL_TRANSFER, &message, sizeof(message));
2040  ao2_ref(chan, -1);
2041  }
2042 }
Main Channel structure associated with a channel.
ast_control_transfer
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1915
Definition: astman.c:222
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_channel_name(const struct ast_channel *chan)
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:1238
struct stasis_forward * sub
Definition: res_corosync.c:240
jack_status_t status
Definition: app_jack.c:146

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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

Definition at line 3438 of file chan_pjsip.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 3438 of file chan_pjsip.c.

◆ call_pickup_supplement

struct ast_sip_session_supplement call_pickup_supplement
static
Initial value:
= {
.method = "INVITE",
.incoming_request = call_pickup_incoming_request,
}
static int call_pickup_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3065

Definition at line 3109 of file chan_pjsip.c.

◆ chan_idx

unsigned int chan_idx
static

Definition at line 80 of file chan_pjsip.c.

Referenced by chan_pjsip_new().

◆ chan_pjsip_ack_supplement

struct ast_sip_session_supplement chan_pjsip_ack_supplement
static
Initial value:
= {
.method = "ACK",
.incoming_request = chan_pjsip_incoming_ack,
}
static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3241

Definition at line 164 of file chan_pjsip.c.

◆ chan_pjsip_dial_contacts_function

struct ast_custom_function chan_pjsip_dial_contacts_function
static
Initial value:
= {
.name = "PJSIP_DIAL_CONTACTS",
}
int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_DIAL_CONTACTS function read callback.

Definition at line 3261 of file chan_pjsip.c.

◆ chan_pjsip_parse_uri_function

struct ast_custom_function chan_pjsip_parse_uri_function
static
Initial value:
= {
.name = "PJSIP_PARSE_URI",
}
int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
PJSIP_PARSE_URI function read callback.

Definition at line 3266 of file chan_pjsip.c.

◆ chan_pjsip_rtp_glue

struct ast_rtp_glue chan_pjsip_rtp_glue
static

Local glue for interacting with the RTP engine core.

Definition at line 486 of file chan_pjsip.c.

◆ chan_pjsip_supplement

struct ast_sip_session_supplement chan_pjsip_supplement
static

SIP session supplement structure.

Definition at line 143 of file chan_pjsip.c.

◆ chan_pjsip_supplement_response

struct ast_sip_session_supplement chan_pjsip_supplement_response
static

SIP session supplement structure just for responses.

Definition at line 155 of file chan_pjsip.c.

◆ chan_pjsip_tech

struct ast_channel_tech chan_pjsip_tech

PBX interface structure for channel registration.

Definition at line 109 of file chan_pjsip.c.

◆ channel_type

const char channel_type[] = "PJSIP"
static

Definition at line 78 of file chan_pjsip.c.

Referenced by load_module().

◆ direct_media_mitigation_info

struct ast_datastore_info direct_media_mitigation_info = { }
static

Definition at line 266 of file chan_pjsip.c.

◆ dtmf_mode_function

struct ast_custom_function dtmf_mode_function
static
Initial value:
= {
.name = "PJSIP_DTMF_MODE",
}
int pjsip_acf_dtmf_mode_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_DTMF_MODE function read callback.
int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_DTMF_MODE function write callback.

Definition at line 3277 of file chan_pjsip.c.

◆ media_offer_function

struct ast_custom_function media_offer_function
static
Initial value:
= {
.name = "PJSIP_MEDIA_OFFER",
}
int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_MEDIA_OFFER function read callback.
int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MEDIA_OFFER function write callback.

Definition at line 3271 of file chan_pjsip.c.

◆ moh_passthrough_function

struct ast_custom_function moh_passthrough_function
static
Initial value:
= {
.name = "PJSIP_MOH_PASSTHROUGH",
}
int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MOH_PASSTHROUGH function write callback.
int pjsip_acf_moh_passthrough_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_MOH_PASSTHROUGH function read callback.

Definition at line 3283 of file chan_pjsip.c.

◆ pbx_start_supplement

struct ast_sip_session_supplement pbx_start_supplement
static
Initial value:
= {
.method = "INVITE",
.incoming_request = pbx_start_incoming_request,
}
static int pbx_start_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3115

Definition at line 3149 of file chan_pjsip.c.

◆ pjsip_uids_onhold

struct ao2_container* pjsip_uids_onhold
static

Definition at line 1107 of file chan_pjsip.c.

◆ refer_callback_module

pjsip_module refer_callback_module
static
Initial value:
= {
.name = { "REFER Callback", 14 },
.id = -1,
}

REFER Callback module, used to attach session data structure to subscription.

Definition at line 1915 of file chan_pjsip.c.

Referenced by load_module(), transfer_refer(), unload_module(), and xfer_client_on_evsub_state().

◆ session_refresh_function

struct ast_custom_function session_refresh_function
static
Initial value:
= {
.name = "PJSIP_SEND_SESSION_REFRESH",
}
int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_SEND_SESSION_REFRESH function write callback.

Definition at line 3289 of file chan_pjsip.c.

◆ transport_info

struct ast_datastore_info transport_info
static
Initial value:
= {
.type = "chan_pjsip_transport_info",
}
static void transport_info_destroy(void *obj)
Destructor function for transport_info_data.
Definition: chan_pjsip.c:253

Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel.

Definition at line 261 of file chan_pjsip.c.

◆ uniqueid_threadbuf

struct ast_threadstorage uniqueid_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_uniqueid_threadbuf , .custom_init = NULL , }
static

Definition at line 75 of file chan_pjsip.c.

Referenced by chan_pjsip_get_uniqueid().