Asterisk - The Open Source Telephony Project GIT-master-a358458
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_prack (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 
static int chan_pjsip_incoming_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 Function called when a request is received on the session. More...
 
static void chan_pjsip_incoming_response (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 Function called when a response is received on the session. More...
 
static void chan_pjsip_incoming_response_update_cause (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 Function called when a response is received on the session. More...
 
static int chan_pjsip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Function called by core to ask the channel to indicate some sort of condition. More...
 
static struct ast_channelchan_pjsip_new (struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
 Function called to create a new PJSIP Asterisk channel. More...
 
static void chan_pjsip_pvt_dtor (void *obj)
 
static int chan_pjsip_queryoption (struct ast_channel *ast, int option, void *data, int *datalen)
 Function called to query options on a channel. More...
 
static struct ast_framechan_pjsip_read_stream (struct ast_channel *ast)
 Function called by core to read any waiting frames. More...
 
static void chan_pjsip_remove_hold (const char *chan_uid)
 Remove a channel ID from the list of PJSIP channels on hold. More...
 
static struct ast_channelchan_pjsip_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 Asterisk core interaction functions. More...
 
static struct ast_channelchan_pjsip_request_with_stream_topology (const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 Function called by core to create a new outgoing PJSIP session. More...
 
static int chan_pjsip_sendtext (struct ast_channel *ast, const char *text)
 
static int chan_pjsip_sendtext_data (struct ast_channel *ast, struct ast_msg_data *msg)
 Function called by core to send text on PJSIP session. More...
 
static void chan_pjsip_session_begin (struct ast_sip_session *session)
 SIP session interaction functions. More...
 
static void chan_pjsip_session_end (struct ast_sip_session *session)
 Function called when the session ends. More...
 
static int chan_pjsip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
 Function called by RTP engine to change where the remote party should send media. More...
 
static int chan_pjsip_transfer (struct ast_channel *chan, const char *target)
 Function called by core for Asterisk initiated transfer. More...
 
static int chan_pjsip_write (struct ast_channel *ast, struct ast_frame *f)
 
static int chan_pjsip_write_stream (struct ast_channel *ast, int stream_num, struct ast_frame *f)
 
static int check_for_rtp_changes (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_sip_session_media *media, struct ast_sip_session *session)
 
static void clear_session_and_channel (struct ast_sip_session *session, struct ast_channel *ast)
 Clear a channel from a session along with its PVT. More...
 
static int compatible_formats_exist (struct ast_stream_topology *top, struct ast_format_cap *cap)
 Determine if a topology is compatible with format capabilities. More...
 
static int direct_media_mitigate_glare (struct ast_sip_session *session)
 
static int handle_topology_request_change (struct ast_sip_session *session, const struct ast_stream_topology *proposed)
 
static int hangup (void *data)
 
static int hangup_cause2sip (int cause)
 Internal function which translates from Asterisk cause codes to SIP response codes. More...
 
static struct hangup_datahangup_data_alloc (int cause, struct ast_channel *chan)
 
static void hangup_data_destroy (void *obj)
 
static int 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 int on_topology_change_response (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
static int pbx_start_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
static int remote_send_hold (void *data)
 Update local hold state to be held. More...
 
static int remote_send_hold_refresh (struct ast_sip_session *session, unsigned int held)
 Update local hold state and send a re-INVITE with the new SDP. More...
 
static int remote_send_unhold (void *data)
 Update local hold state to be unheld. More...
 
static int request (void *obj)
 
static struct rtp_direct_media_datartp_direct_media_data_create (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, const struct ast_format_cap *cap, struct ast_sip_session *session)
 
static void rtp_direct_media_data_destroy (void *data)
 
static int rtp_find_rtcp_fd_position (struct ast_sip_session *session, struct ast_rtp_instance *rtp)
 Helper function to find the position for RTCP. More...
 
static int send_direct_media_request (void *data)
 
static int send_topology_change_refresh (void *data)
 
static int sendtext (void *obj)
 
static struct sendtext_datasendtext_data_create (struct ast_channel *chan, struct ast_msg_data *msg)
 
static void sendtext_data_destroy (void *obj)
 
static void set_channel_on_rtp_instance (const struct ast_sip_session *session, const char *channel_id)
 
static void set_sipdomain_variable (struct ast_sip_session *session)
 
static struct topology_change_refresh_datatopology_change_refresh_data_alloc (struct ast_sip_session *session, const struct ast_stream_topology *topology)
 
static void topology_change_refresh_data_free (struct topology_change_refresh_data *refresh_data)
 
static int transfer (void *data)
 
static struct transfer_datatransfer_data_alloc (struct ast_sip_session *session, const char *target)
 
static void transfer_data_destroy (void *obj)
 
static void transfer_redirect (struct ast_sip_session *session, const char *target)
 
static void transfer_refer (struct ast_sip_session *session, const char *target)
 
static int transmit_info_dtmf (void *data)
 
static int transmit_info_with_vidupdate (void *data)
 Send SIP INFO with video update request. More...
 
static void transport_info_destroy (void *obj)
 Destructor function for transport_info_data. More...
 
static int uid_hold_hash_fn (const void *obj, const int flags)
 
static int uid_hold_sort_fn (const void *obj_left, const void *obj_right, const int flags)
 
static int unload_module (void)
 Unload the PJSIP channel from Asterisk. More...
 
static int update_connected_line_information (void *data)
 Update connected line information. More...
 
static int update_devstate (void *obj, void *arg, int flags)
 
static void update_initial_connected_line (struct ast_sip_session *session)
 
static void xfer_client_on_evsub_state (pjsip_evsub *sub, pjsip_event *event)
 Callback function to report status of implicit REFER-NOTIFY subscription. More...
 

Variables

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

Detailed Description

PSJIP SIP Channel Driver.

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

Definition in file chan_pjsip.c.

Macro Definition Documentation

◆ UNIQUEID_BUFSIZE

#define UNIQUEID_BUFSIZE   256

Definition at line 76 of file chan_pjsip.c.

Function Documentation

◆ __init_uniqueid_threadbuf()

static void __init_uniqueid_threadbuf ( void  )
static

Definition at line 75 of file chan_pjsip.c.

83{

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3430 of file chan_pjsip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3430 of file chan_pjsip.c.

◆ answer()

static int answer ( void *  data)
static

Definition at line 683 of file chan_pjsip.c.

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

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

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

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 3430 of file chan_pjsip.c.

◆ call()

static int call ( void *  data)
static

Definition at line 2391 of file chan_pjsip.c.

2392{
2393 struct ast_sip_channel_pvt *channel = data;
2394 struct ast_sip_session *session = channel->session;
2395 pjsip_tx_data *tdata;
2396 int res = 0;
2397 SCOPE_ENTER(1, "%s Topology: %s\n",
2399 ast_str_tmp(256, ast_stream_topology_to_str(channel->session->pending_media_state->topology, &STR_TMP))
2400 );
2401
2402
2404
2405 if (res) {
2406 ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2407 ast_queue_hangup(session->channel);
2408 } else {
2412 }
2413 ao2_ref(channel, -1);
2414 SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
2415}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static void update_initial_connected_line(struct ast_sip_session *session)
Definition: chan_pjsip.c:2366
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:494
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
Definition: channel.c:2499
#define SCOPE_ENTER(level,...)
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
Creates an INVITE request.
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1189
A structure which contains a channel implementation and session.
struct ast_channel * channel

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

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

◆ call_pickup_incoming_request()

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

Definition at line 3026 of file chan_pjsip.c.

3027{
3028 struct ast_features_pickup_config *pickup_cfg;
3029 struct ast_channel *chan;
3030
3031 /* Check for a to-tag to determine if this is a reinvite */
3032 if (rdata->msg_info.to->tag.slen) {
3033 /* We don't care about reinvites */
3034 return 0;
3035 }
3036
3037 pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
3038 if (!pickup_cfg) {
3039 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
3040 return 0;
3041 }
3042
3043 if (strcmp(session->exten, pickup_cfg->pickupexten)) {
3044 ao2_ref(pickup_cfg, -1);
3045 return 0;
3046 }
3047 ao2_ref(pickup_cfg, -1);
3048
3049 /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
3050 * changing the channel pointer in session to a different channel. To ensure we work on the right channel
3051 * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
3052 */
3053 chan = ast_channel_ref(session->channel);
3054 if (ast_pickup_call(chan)) {
3056 } else {
3058 }
3059 /* A hangup always occurs because the pickup operation will have either failed resulting in the call
3060 * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
3061 * the channel that was replaced, which should be hung up since it is literally in limbo not connected
3062 * to anything at all.
3063 */
3064 ast_hangup(chan);
3065 ast_channel_unref(chan);
3066
3067 return 1;
3068}
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:111
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:199
Main Channel structure associated with a channel.
Configuration relating to call pickup.

References ao2_ref, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_hangupcause_set(), ast_channel_ref, ast_channel_unref, ast_get_chan_features_pickup_config(), ast_hangup(), ast_log, ast_pickup_call(), LOG_ERROR, ast_features_pickup_config::pickupexten, and session.

◆ chan_pjsip_add_hold()

static int chan_pjsip_add_hold ( const char *  chan_uid)
static

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

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

Definition at line 1118 of file chan_pjsip.c.

1119{
1120 RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1121
1122 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1123 if (hold_uid) {
1124 /* Device is already on hold. Nothing to do. */
1125 return 0;
1126 }
1127
1128 /* Device wasn't in hold list already. Create a new one. */
1129 hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
1131 if (!hold_uid) {
1132 return -1;
1133 }
1134
1135 ast_copy_string(hold_uid, chan_uid, strlen(chan_uid) + 1);
1136
1137 if (ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
1138 return -1;
1139 }
1140
1141 return 0;
1142}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1108
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
#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:941

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

Referenced by chan_pjsip_indicate().

◆ chan_pjsip_answer()

static int chan_pjsip_answer ( struct ast_channel ast)
static

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

Definition at line 727 of file chan_pjsip.c.

728{
729 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
730 struct ast_sip_session *session;
731 struct answer_data ans_data = { 0, };
732 int res;
733 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
734
735 if (ast_channel_state(ast) == AST_STATE_UP) {
736 SCOPE_EXIT_RTN_VALUE(0, "Already up\n");
737 return 0;
738 }
739
741 session = ao2_bump(channel->session);
742
743 /* the answer task needs to be pushed synchronously otherwise a race condition
744 can occur between this thread and bridging (specifically when native bridging
745 attempts to do direct media) */
747 ans_data.session = session;
748 ans_data.indent = ast_trace_get_indent();
749 res = ast_sip_push_task_wait_serializer(session->serializer, answer, &ans_data);
750 if (res) {
751 if (res == -1) {
752 ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
753 ast_channel_name(session->channel));
754 }
755 ao2_ref(session, -1);
756 ast_channel_lock(ast);
757 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
758 }
759 ao2_ref(session, -1);
760 ast_channel_lock(ast);
761
763}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static int answer(void *data)
Definition: chan_pjsip.c:683
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7386
#define ast_trace_get_indent()
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:2179
struct ast_sip_session * session
Pointer to session.

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

◆ chan_pjsip_call()

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

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

Definition at line 2418 of file chan_pjsip.c.

2419{
2420 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2421 SCOPE_ENTER(1, "%s Topology: %s\n", ast_sip_session_get_name(channel->session),
2423
2424 ao2_ref(channel, +1);
2425 if (ast_sip_push_task(channel->session->serializer, call, channel)) {
2426 ast_log(LOG_WARNING, "Error attempting to place outbound call to '%s'\n", dest);
2427 ao2_cleanup(channel);
2428 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
2429 }
2430
2431 SCOPE_EXIT_RTN_VALUE(0, "'call' task pushed\n");
2432}
static int call(void *data)
Definition: chan_pjsip.c:2391
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:2099
struct ast_stream_topology * topology
The media stream topology.
struct ast_sip_session_media_state * pending_media_state
struct ast_taskprocessor * serializer

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

◆ chan_pjsip_cng_tone_detected()

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

Internal helper function called when CNG tone is detected.

Definition at line 766 of file chan_pjsip.c.

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

References ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_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, exists(), LOG_ERROR, LOG_NOTICE, NULL, pbx_builtin_setvar_helper(), S_COR, and session.

Referenced by chan_pjsip_read_stream().

◆ chan_pjsip_devicestate()

static int chan_pjsip_devicestate ( const char *  data)
static

Function called to get the device state of an endpoint.

Definition at line 1175 of file chan_pjsip.c.

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

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.

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

2184{
2185 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2186 struct ast_sip_session_media *media;
2187
2189
2190 switch (channel->session->dtmf) {
2192 if (!media || !media->rtp) {
2193 return 0;
2194 }
2195
2197 break;
2198 case AST_SIP_DTMF_AUTO:
2199 if (!media || !media->rtp) {
2200 return 0;
2201 }
2202
2204 return -1;
2205 }
2206
2208 break;
2210 if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) {
2211 return 0;
2212 }
2214 break;
2215 case AST_SIP_DTMF_NONE:
2216 break;
2218 return -1;
2219 default:
2220 break;
2221 }
2222
2223 return 0;
2224}
char digit
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_SIP_DTMF_NONE
Definition: res_pjsip.h:545
@ AST_SIP_DTMF_AUTO_INFO
Definition: res_pjsip.h:556
@ AST_SIP_DTMF_AUTO
Definition: res_pjsip.h:554
@ AST_SIP_DTMF_INBAND
Definition: res_pjsip.h:550
@ AST_SIP_DTMF_RFC_4733
Definition: res_pjsip.h:548
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:2150
@ AST_RTP_DTMF_MODE_INBAND
Definition: rtp_engine.h:154
@ AST_RTP_DTMF_MODE_NONE
Definition: rtp_engine.h:150
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2094
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
struct ast_sip_session_media_state * active_media_state
enum ast_sip_dtmf_mode dtmf

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

◆ chan_pjsip_digit_end()

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

Function called by core to stop a DTMF digit.

Definition at line 2295 of file chan_pjsip.c.

2296{
2297 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2298 struct ast_sip_session_media *media;
2299
2300 if (!channel || !channel->session) {
2301 /* This happens when the channel is hungup while a DTMF digit is playing. See ASTERISK-28086 */
2302 ast_debug(3, "Channel %s disappeared while calling digit_end\n", ast_channel_name(ast));
2303 return -1;
2304 }
2305
2307
2308 switch (channel->session->dtmf) {
2310 {
2311 if (!media || !media->rtp) {
2312 return 0;
2313 }
2314
2316 ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));
2318 break;
2319 }
2320 /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */
2321 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));
2322 }
2323
2324 case AST_SIP_DTMF_INFO:
2325 {
2326 struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
2327
2328 if (!dtmf_data) {
2329 return -1;
2330 }
2331
2332 if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
2333 ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
2334 ao2_cleanup(dtmf_data);
2335 return -1;
2336 }
2337 break;
2338 }
2340 if (!media || !media->rtp) {
2341 return 0;
2342 }
2343
2345 break;
2346 case AST_SIP_DTMF_AUTO:
2347 if (!media || !media->rtp) {
2348 return 0;
2349 }
2350
2352 return -1;
2353 }
2354
2356 break;
2357 case AST_SIP_DTMF_NONE:
2358 break;
2360 return -1;
2361 }
2362
2363 return 0;
2364}
static int transmit_info_dtmf(void *data)
Definition: chan_pjsip.c:2251
static struct info_dtmf_data * info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
Definition: chan_pjsip.c:2238
#define ast_debug(level,...)
Log a DEBUG message.
@ AST_SIP_DTMF_INFO
Definition: res_pjsip.h:552
int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
Definition: rtp_engine.c:2122
unsigned int duration
Definition: chan_pjsip.c:2229

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

◆ chan_pjsip_fixup()

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

Function called by core to change the underlying owner channel.

Definition at line 1046 of file chan_pjsip.c.

1047{
1048 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(newchan);
1049
1050 if (channel->session->channel != oldchan) {
1051 return -1;
1052 }
1053
1054 /*
1055 * The masquerade has suspended the channel's session
1056 * serializer so we can safely change it outside of
1057 * the serializer thread.
1058 */
1059 channel->session->channel = newchan;
1060
1062
1063 return 0;
1064}

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

◆ chan_pjsip_get_codec()

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

Function called by RTP engine to get peer capabilities.

Definition at line 252 of file chan_pjsip.c.

253{
254 SCOPE_ENTER(1, "%s Native formats %s\n", ast_channel_name(chan),
258}
static PGresult * result
Definition: cel_pgsql.c:84
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
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
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
#define SCOPE_EXIT_RTN(...)

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

◆ chan_pjsip_get_hold()

static int chan_pjsip_get_hold ( const char *  chan_uid)
static

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

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

Definition at line 1162 of file chan_pjsip.c.

1163{
1164 RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1165
1166 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1167 if (!hold_uid) {
1168 return 0;
1169 }
1170
1171 return 1;
1172}

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

Referenced by chan_pjsip_devicestate().

◆ chan_pjsip_get_rtp_peer()

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

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

Definition at line 179 of file chan_pjsip.c.

180{
181 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
182 struct ast_sip_endpoint *endpoint;
183 struct ast_datastore *datastore;
184 struct ast_sip_session_media *media;
185
186 if (!channel || !channel->session) {
188 }
189
190 /* XXX Getting the first RTP instance for direct media related stuff seems just
191 * absolutely wrong. But the native RTP bridge knows no other method than single-stream
192 * for direct media. So this is the best we can do.
193 */
195 if (!media || !media->rtp) {
197 }
198
199 datastore = ast_sip_session_get_datastore(channel->session, "t38");
200 if (datastore) {
201 ao2_ref(datastore, -1);
203 }
204
205 endpoint = channel->session->endpoint;
206
207 *instance = media->rtp;
208 ao2_ref(*instance, +1);
209
210 ast_assert(endpoint != NULL);
213 }
214
215 if (endpoint->media.direct_media.enabled) {
217 }
218
220}
@ AST_SIP_MEDIA_ENCRYPT_NONE
Definition: res_pjsip.h:649
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
@ AST_RTP_GLUE_RESULT_LOCAL
Definition: rtp_engine.h:164
@ AST_RTP_GLUE_RESULT_REMOTE
Definition: rtp_engine.h:162
@ AST_RTP_GLUE_RESULT_FORBID
Definition: rtp_engine.h:160
Structure for a data store object.
Definition: datastore.h:64
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:915
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:917
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:996
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:858
struct ast_sip_endpoint * endpoint
#define ast_assert(a)
Definition: utils.h:739

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

◆ chan_pjsip_get_uniqueid()

static const char * chan_pjsip_get_uniqueid ( struct ast_channel ast)
static

Definition at line 1279 of file chan_pjsip.c.

1280{
1281 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1283
1284 if (!channel || !uniqueid) {
1285 return "";
1286 }
1287
1288 ast_copy_pj_str(uniqueid, &channel->session->inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
1289
1290 return uniqueid;
1291}
#define UNIQUEID_BUFSIZE
Definition: chan_pjsip.c:76
static struct ast_threadstorage uniqueid_threadbuf
Definition: chan_pjsip.c:75
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:2201
struct pjsip_inv_session * inv_session
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.

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

◆ chan_pjsip_get_vrtp_peer()

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

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

Definition at line 223 of file chan_pjsip.c.

224{
225 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
226 struct ast_sip_endpoint *endpoint;
227 struct ast_sip_session_media *media;
228
229 if (!channel || !channel->session) {
231 }
232
234 if (!media || !media->rtp) {
236 }
237
238 endpoint = channel->session->endpoint;
239
240 *instance = media->rtp;
241 ao2_ref(*instance, +1);
242
243 ast_assert(endpoint != NULL);
246 }
247
249}
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33

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

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

2559{
2560 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2561 int cause;
2562 struct hangup_data *h_data;
2563 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2564
2565 if (!channel || !channel->session) {
2566 SCOPE_EXIT_RTN_VALUE(-1, "No channel or session\n");
2567 }
2568
2570 h_data = hangup_data_alloc(cause, ast);
2571
2572 if (!h_data) {
2573 goto failure;
2574 }
2575
2576 if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
2577 ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
2578 goto failure;
2579 }
2580
2581 SCOPE_EXIT_RTN_VALUE(0, "Cause: %d\n", cause);
2582
2583failure:
2584 /* Go ahead and do our cleanup of the session and channel even if we're not going
2585 * to be able to send our SIP request/response
2586 */
2587 clear_session_and_channel(channel->session, ast);
2588 ao2_cleanup(channel);
2589 ao2_cleanup(h_data);
2590
2591 SCOPE_EXIT_RTN_VALUE(-1, "Cause: %d\n", cause);
2592}
static int hangup_cause2sip(int cause)
Internal function which translates from Asterisk cause codes to SIP response codes.
Definition: chan_pjsip.c:2435
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:2509
static int hangup(void *data)
Definition: chan_pjsip.c:2516
static struct hangup_data * hangup_data_alloc(int cause, struct ast_channel *chan)
Definition: chan_pjsip.c:2494
int ast_channel_hangupcause(const struct ast_channel *chan)

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

◆ chan_pjsip_incoming_ack()

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

Definition at line 3204 of file chan_pjsip.c.

3205{
3207
3208 if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
3209 if (session->endpoint->media.direct_media.enabled && session->channel) {
3210 ast_trace(-1, "%s: Queueing SRCCHANGE\n", ast_sip_session_get_name(session));
3212 }
3213 }
3215}
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,...)
@ AST_CONTROL_SRCCHANGE

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

◆ chan_pjsip_incoming_prack()

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

Definition at line 3217 of file chan_pjsip.c.

3218{
3220
3221 if (pj_strcmp2(&rdata->msg_info.msg->line.req.method.name, "PRACK") == 0 &&
3222 pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE) {
3223
3224 session->early_confirmed = 1;
3225 }
3227}

References ast_sip_session_get_name(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and session.

◆ chan_pjsip_incoming_request()

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

Function called when a request is received on the session.

Definition at line 2968 of file chan_pjsip.c.

2969{
2970 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
2971 struct transport_info_data *transport_data;
2972 pjsip_tx_data *packet = NULL;
2974
2975 if (session->channel) {
2976 SCOPE_EXIT_RTN_VALUE(0, "%s: No channel\n", ast_sip_session_get_name(session));
2977 }
2978
2979 /* Check for a to-tag to determine if this is a reinvite */
2980 if (rdata->msg_info.to->tag.slen) {
2981 /* Weird case. We've received a reinvite but we don't have a channel. The most
2982 * typical case for this happening is that a blind transfer fails, and so the
2983 * transferer attempts to reinvite himself back into the call. We already got
2984 * rid of that channel, and the other side of the call is unrecoverable.
2985 *
2986 * We treat this as a failure, so our best bet is to just hang this call
2987 * up and not create a new channel. Clearing defer_terminate here ensures that
2988 * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
2989 */
2990 session->defer_terminate = 0;
2992 SCOPE_EXIT_RTN_VALUE(-1, "%s: We have a To tag but no channel. Terminating session\n", ast_sip_session_get_name(session));
2993 }
2994
2995 datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
2996 if (!datastore) {
2997 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info datastore\n", ast_sip_session_get_name(session));
2998 }
2999
3000 transport_data = ast_calloc(1, sizeof(*transport_data));
3001 if (!transport_data) {
3002 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info\n", ast_sip_session_get_name(session));
3003 }
3004 pj_sockaddr_cp(&transport_data->local_addr, &rdata->tp_info.transport->local_addr);
3005 pj_sockaddr_cp(&transport_data->remote_addr, &rdata->pkt_info.src_addr);
3006 datastore->data = transport_data;
3008
3009 if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
3010 if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS
3011 && packet) {
3013 }
3014
3015 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Failed to allocate new PJSIP channel on incoming SIP INVITE\n",
3017 }
3018
3020
3021 /* channel gets created on incoming request, but we wait to call start
3022 so other supplements have a chance to run */
3024}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static struct ast_datastore_info transport_info
Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel.
Definition: chan_pjsip.c:269
static void set_sipdomain_variable(struct ast_sip_session *session)
Definition: chan_pjsip.c:2955
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 SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
Transport information stored in transport_info datastore.
Definition: chan_pjsip.h:30
pj_sockaddr local_addr
Our address that received the request.
Definition: chan_pjsip.h:34
pj_sockaddr remote_addr
The address that sent the request.
Definition: chan_pjsip.h:32

References ao2_cleanup, ast_calloc, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_name(), ast_sip_session_send_response(), ast_sip_session_terminate(), AST_STATE_RING, chan_pjsip_new(), transport_info_data::local_addr, LOG_ERROR, NULL, RAII_VAR, transport_info_data::remote_addr, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, session, set_sipdomain_variable(), and transport_info.

◆ chan_pjsip_incoming_response()

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

Function called when a response is received on the session.

Definition at line 3147 of file chan_pjsip.c.

3148{
3149 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3150 SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3151
3152 if (!session->channel) {
3153 SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3154 }
3155
3156 switch (status.code) {
3157 case 180: {
3158 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3159 if (sdp && sdp->body.ptr) {
3160 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3161 session->early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3163 } else {
3164 ast_trace(-1, "%s: Queueing RINGING\n", ast_sip_session_get_name(session));
3166 }
3167
3168 ast_channel_lock(session->channel);
3169 if (ast_channel_state(session->channel) != AST_STATE_UP) {
3171 }
3172 ast_channel_unlock(session->channel);
3173 break;
3174 }
3175 case 183:
3176 if (session->endpoint->ignore_183_without_sdp) {
3177 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3178 if (sdp && sdp->body.ptr) {
3179 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3180 ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS with SDP\n", ast_sip_session_get_name(session),
3181 (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3182 session->early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3184 }
3185 } else {
3186 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3187 ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS without SDP\n", ast_sip_session_get_name(session),
3188 (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3190 }
3191 break;
3192 case 200:
3193 ast_trace(-1, "%s: Queueing ANSWER\n", ast_sip_session_get_name(session));
3195 break;
3196 default:
3197 ast_trace(-1, "%s: Not queueing anything\n", ast_sip_session_get_name(session));
3198 break;
3199 }
3200
3202}
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING

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

◆ chan_pjsip_incoming_response_update_cause()

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

Function called when a response is received on the session.

Definition at line 3117 of file chan_pjsip.c.

3118{
3119 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3120 struct ast_control_pvt_cause_code *cause_code;
3121 int data_size = sizeof(*cause_code);
3122 SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3123
3124 if (!session->channel) {
3125 SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3126 }
3127
3128 /* Build and send the tech-specific cause information */
3129 /* size of the string making up the cause code is "SIP " number + " " + reason length */
3130 data_size += 4 + 4 + pj_strlen(&status.reason);
3131 cause_code = ast_alloca(data_size);
3132 memset(cause_code, 0, data_size);
3133
3135
3136 snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
3137 (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
3138
3139 cause_code->ast_cause = ast_sip_hangup_sip2cause(status.code);
3140 ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
3141 ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
3142
3144}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
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:4346
#define AST_CHANNEL_NAME
Definition: channel.h:171
@ AST_CONTROL_PVT_CAUSE_CODE
const int ast_sip_hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: res_pjsip.c:3531
char chan_name[AST_CHANNEL_NAME]

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

◆ chan_pjsip_indicate()

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

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

Definition at line 1621 of file chan_pjsip.c.

1622{
1623 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1624 struct ast_sip_session_media *media;
1625 int response_code = 0;
1626 int res = 0;
1627 char *device_buf;
1628 size_t device_buf_size;
1629 int i;
1630 const struct ast_stream_topology *topology;
1631 struct ast_frame f = {
1633 .subclass = {
1634 .integer = condition
1635 },
1636 .datalen = datalen,
1637 .data.ptr = (void *)data,
1638 };
1639 char condition_name[256];
1640 unsigned int duration;
1641 char digit;
1642 struct info_dtmf_data *dtmf_data;
1643
1644 SCOPE_ENTER(3, "%s: Indicated %s\n", ast_channel_name(ast),
1645 ast_frame_subclass2str(&f, condition_name, sizeof(condition_name), NULL, 0));
1646
1647 switch (condition) {
1649 if (ast_channel_state(ast) == AST_STATE_RING) {
1650 if (channel->session->endpoint->inband_progress ||
1651 (channel->session->inv_session && channel->session->inv_session->neg &&
1652 pjmedia_sdp_neg_get_state(channel->session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE)) {
1653 res = -1;
1655 response_code = 180;
1656 } else {
1657 response_code = 183;
1658 }
1659 } else {
1660 response_code = 180;
1661 }
1662 } else {
1663 res = -1;
1664 }
1666 break;
1667 case AST_CONTROL_BUSY:
1668 if (ast_channel_state(ast) != AST_STATE_UP) {
1669 response_code = 486;
1670 } else {
1671 res = -1;
1672 }
1673 break;
1675 if (ast_channel_state(ast) != AST_STATE_UP) {
1676 response_code = 503;
1677 } else {
1678 res = -1;
1679 }
1680 break;
1682 if (ast_channel_state(ast) != AST_STATE_UP) {
1683 response_code = 484;
1684 } else {
1685 res = -1;
1686 }
1687 break;
1689 if (ast_channel_state(ast) != AST_STATE_UP) {
1690 response_code = 100;
1691 } else {
1692 res = -1;
1693 }
1694 break;
1696 if (ast_channel_state(ast) != AST_STATE_UP) {
1697 response_code = 183;
1698 } else {
1699 res = -1;
1700 }
1702 break;
1703 case AST_CONTROL_FLASH:
1704 duration = 300;
1705 digit = '!';
1706 dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
1707
1708 if (!dtmf_data) {
1709 res = -1;
1710 break;
1711 }
1712
1713 if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
1714 ast_log(LOG_WARNING, "Error sending FLASH via INFO on channel %s\n", ast_channel_name(ast));
1715 ao2_ref(dtmf_data, -1); /* dtmf_data can't be null here */
1716 res = -1;
1717 }
1718 break;
1720 for (i = 0; i < AST_VECTOR_SIZE(&channel->session->active_media_state->sessions); ++i) {
1721 media = AST_VECTOR_GET(&channel->session->active_media_state->sessions, i);
1722 if (!media || media->type != AST_MEDIA_TYPE_VIDEO) {
1723 continue;
1724 }
1725 if (media->rtp) {
1726 /* FIXME: Only use this for VP8. Additional work would have to be done to
1727 * fully support other video codecs */
1728
1732 (channel->session->endpoint->media.webrtc &&
1734 /* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
1735 * RTP engine would provide a way to externally write/schedule RTCP
1736 * packets */
1737 struct ast_frame fr;
1739 fr.subclass.integer = AST_CONTROL_VIDUPDATE;
1740 res = ast_rtp_instance_write(media->rtp, &fr);
1741 } else {
1742 ao2_ref(channel->session, +1);
1744 ao2_cleanup(channel->session);
1745 }
1746 }
1747 ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
1748 } else {
1749 ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
1750 res = -1;
1751 }
1752 }
1753 /* XXX If there were no video streams, then this should set
1754 * res to -1
1755 */
1756 break;
1758 ao2_ref(channel->session, +1);
1760 ao2_cleanup(channel->session);
1761 }
1762 break;
1764 break;
1766 res = -1;
1767 break;
1769 ast_assert(datalen == sizeof(int));
1770 if (*(int *) data) {
1771 /*
1772 * Masquerade is beginning:
1773 * Wait for session serializer to get suspended.
1774 */
1775 ast_channel_unlock(ast);
1777 ast_channel_lock(ast);
1778 } else {
1779 /*
1780 * Masquerade is complete:
1781 * Unsuspend the session serializer.
1782 */
1784 }
1785 break;
1786 case AST_CONTROL_HOLD:
1788 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1789 device_buf = alloca(device_buf_size);
1790 ast_channel_get_device_name(ast, device_buf, device_buf_size);
1792 if (!channel->session->moh_passthrough) {
1793 ast_moh_start(ast, data, NULL);
1794 } else {
1796 ast_log(LOG_WARNING, "Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
1798 ao2_ref(channel->session, -1);
1799 }
1800 }
1801 break;
1802 case AST_CONTROL_UNHOLD:
1804 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1805 device_buf = alloca(device_buf_size);
1806 ast_channel_get_device_name(ast, device_buf, device_buf_size);
1808 if (!channel->session->moh_passthrough) {
1809 ast_moh_stop(ast);
1810 } else {
1812 ast_log(LOG_WARNING, "Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
1814 ao2_ref(channel->session, -1);
1815 }
1816 }
1817 break;
1819 break;
1821 break;
1823 if (ast_channel_state(ast) != AST_STATE_UP) {
1824 response_code = 181;
1825 } else {
1826 res = -1;
1827 }
1828 break;
1830 res = 0;
1831
1832 if (channel->session->t38state == T38_PEER_REINVITE) {
1833 const struct ast_control_t38_parameters *parameters = data;
1834
1835 if (parameters->request_response == AST_T38_REQUEST_PARMS) {
1837 }
1838 }
1839
1840 break;
1842 topology = data;
1843 ast_trace(-1, "%s: New topology: %s\n", ast_channel_name(ast),
1844 ast_str_tmp(256, ast_stream_topology_to_str(topology, &STR_TMP)));
1845 res = handle_topology_request_change(channel->session, topology);
1846 break;
1848 break;
1850 break;
1851 case -1:
1852 res = -1;
1853 break;
1854 default:
1855 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
1856 res = -1;
1857 break;
1858 }
1859
1860 if (response_code) {
1861 struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
1862
1863 if (!ind_data) {
1864 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
1865 }
1866
1867 if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
1868 ast_log(LOG_ERROR, "%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
1870 ao2_cleanup(ind_data);
1871 res = -1;
1872 }
1873 }
1874
1875 SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_channel_name(ast));
1876}
static int update_connected_line_information(void *data)
Update connected line information.
Definition: chan_pjsip.c:1430
static int remote_send_unhold(void *data)
Update local hold state to be unheld.
Definition: chan_pjsip.c:1502
static int handle_topology_request_change(struct ast_sip_session *session, const struct ast_stream_topology *proposed)
Definition: chan_pjsip.c:1597
static int indicate(void *data)
Definition: chan_pjsip.c:1334
static int remote_send_hold(void *data)
Update local hold state to be held.
Definition: chan_pjsip.c:1496
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:1309
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:1149
static int transmit_info_with_vidupdate(void *data)
Send SIP INFO with video update request.
Definition: chan_pjsip.c:1352
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:1118
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:10496
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:471
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
struct ast_format * ast_format_h264
Built-in cached h264 format.
Definition: format_cache.c:176
struct ast_format * ast_format_h265
Built-in cached h265 format.
Definition: format_cache.c:181
struct ast_format * ast_format_vp9
Built-in cached vp9 format.
Definition: format_cache.c:196
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:191
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:581
@ AST_T38_REQUEST_PARMS
char * ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
Copy the discription of a frame's subclass into the provided string.
Definition: main/frame.c:406
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_HOLD
@ AST_CONTROL_STREAM_TOPOLOGY_CHANGED
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_FLASH
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_UPDATE_RTP_PEER
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7766
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7776
unsigned int ast_sip_get_allow_sending_180_after_183(void)
Retrieve the global setting 'allow_sending_180_after_183'.
@ T38_PEER_REINVITE
void ast_sip_session_unsuspend(struct ast_sip_session *session)
Request the session serializer be unsuspended.
void ast_sip_session_suspend(struct ast_sip_session *session)
Request and wait for the session serializer to be suspended.
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:589
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
enum ast_control_t38 request_response
Data structure associated with a single frame of data.
union ast_frame::@226 data
enum ast_frame_type frametype
unsigned int inband_progress
Definition: res_pjsip.h:1018
struct ast_sip_session_media_state::@263 sessions
Mapping of stream to media sessions.
enum ast_media_type type
Media type of this session media.
enum ast_sip_session_t38state t38state
unsigned int moh_passthrough
size_t datalen
Definition: chan_pjsip.c:1298
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

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

◆ chan_pjsip_new()

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

Function called to create a new PJSIP Asterisk channel.

Definition at line 547 of file chan_pjsip.c.

548{
549 struct ast_channel *chan;
550 struct ast_format_cap *caps;
551 RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
552 struct ast_sip_channel_pvt *channel;
553 struct ast_variable *var;
554 struct ast_stream_topology *topology;
556
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
584 if (!ast_stream_topology_get_count(session->pending_media_state->topology) ||
585 !compatible_formats_exist(session->pending_media_state->topology, session->endpoint->media.codecs)) {
587 if (!caps) {
588 ast_channel_unlock(chan);
589 ast_hangup(chan);
590 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create caps\n");
591 }
592 ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN);
593 topology = ast_stream_topology_clone(session->endpoint->media.topology);
594 } else {
595 caps = ast_stream_topology_get_formats(session->pending_media_state->topology);
596 topology = ast_stream_topology_clone(session->pending_media_state->topology);
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
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 }
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
637 ast_channel_caller(chan)->ani2 = session->ani2;
638
639 if (!ast_strlen_zero(exten)) {
640 /* Set provided DNID on the new channel. */
641 ast_channel_dialed(chan)->number.str = ast_strdup(exten);
642 }
643
645
646 ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
647 ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup);
648
649 ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups);
650 ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups);
651
652 if (!ast_strlen_zero(session->endpoint->language)) {
653 ast_channel_language_set(chan, session->endpoint->language);
654 }
655
656 if (!ast_strlen_zero(session->endpoint->zone)) {
657 struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
658 if (!zone) {
659 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
660 }
661 ast_channel_zone_set(chan, zone);
662 }
663
664 for (var = session->endpoint->channel_vars; var; var = var->next) {
665 char buf[512];
667 var->value, buf, sizeof(buf)));
668 }
669
671 ast_channel_unlock(chan);
672
674
676}
#define var
Definition: ast_expr2f.c:605
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
static void chan_pjsip_pvt_dtor(void *obj)
Definition: chan_pjsip.c:82
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
static int compatible_formats_exist(struct ast_stream_topology *top, struct ast_format_cap *cap)
Determine if a topology is compatible with format capabilities.
Definition: chan_pjsip.c:526
static unsigned int chan_idx
Definition: chan_pjsip.c:80
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
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.
#define ast_channel_alloc_with_endpoint(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint,...)
Definition: channel.h:1262
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:871
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition: channel.c:1765
void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:744
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition: format_cap.c:417
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3152
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:439
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:757
struct ast_sip_channel_pvt * ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session)
Allocate a new SIP channel pvt structure.
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
Definition: stream.c:930
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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:433
struct ast_party_dialed::@208 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:386
A set of tones for a given locale.
Definition: indications.h:74
Structure for variables, used for configurations and for channel variables.
The PJSIP channel driver pvt, stored in the ast_sip_channel_pvt data structure.
Definition: chan_pjsip.h:42

References ast_party_caller::ani2, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_channel_adsicpe_set(), ast_channel_alloc_with_endpoint, ast_channel_caller(), ast_channel_callgroup_set(), ast_channel_dialed(), ast_channel_named_callgroups_set(), ast_channel_named_pickupgroups_set(), ast_channel_nativeformats_set(), ast_channel_pickupgroup_set(), ast_channel_priority_set(), ast_channel_rings_set(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_stream_topology(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_zone_set(), ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_empty(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_best_by_type(), ast_format_cap_get_format(), ast_get_encoded_str(), ast_get_indication_zone(), ast_hangup(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, ast_party_id_copy(), ast_sip_channel_pvt_alloc(), ast_sip_session_get_name(), ast_sorcery_object_get_id(), AST_STATE_RING, ast_strdup, ast_stream_topology_clone(), ast_stream_topology_free(), ast_stream_topology_get_count(), ast_stream_topology_get_formats(), ast_strlen_zero(), buf, chan_idx, chan_pjsip_pvt_dtor(), chan_pjsip_tech, compatible_formats_exist(), LOG_ERROR, NULL, ast_party_dialed::number, pbx_builtin_setvar_helper(), RAII_VAR, S_COR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, set_channel_on_rtp_instance(), ast_party_dialed::str, and var.

Referenced by chan_pjsip_incoming_request(), and chan_pjsip_request_with_stream_topology().

◆ chan_pjsip_pvt_dtor()

static void chan_pjsip_pvt_dtor ( void *  obj)
static

Definition at line 82 of file chan_pjsip.c.

83{
84}

Referenced by chan_pjsip_new().

◆ chan_pjsip_queryoption()

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

Function called to query options on a channel.

Definition at line 1238 of file chan_pjsip.c.

1239{
1240 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1241 int res = -1;
1243
1244 if (!channel) {
1245 return -1;
1246 }
1247
1248 switch (option) {
1250 if (channel->session->endpoint->media.t38.enabled) {
1251 switch (channel->session->t38state) {
1252 case T38_LOCAL_REINVITE:
1253 case T38_PEER_REINVITE:
1255 break;
1256 case T38_ENABLED:
1258 break;
1259 case T38_REJECTED:
1261 break;
1262 default:
1264 break;
1265 }
1266 }
1267
1268 *((enum ast_t38_state *) data) = state;
1269 res = 0;
1270
1271 break;
1272 default:
1273 break;
1274 }
1275
1276 return res;
1277}
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:878
@ T38_STATE_UNAVAILABLE
Definition: channel.h:879
@ T38_STATE_UNKNOWN
Definition: channel.h:880
@ T38_STATE_REJECTED
Definition: channel.h:882
@ T38_STATE_NEGOTIATED
Definition: channel.h:883
@ T38_STATE_NEGOTIATING
Definition: channel.h:881
#define AST_OPTION_T38_STATE
@ T38_LOCAL_REINVITE
@ T38_ENABLED
@ T38_REJECTED
struct ast_sip_t38_configuration t38
Definition: res_pjsip.h:919

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

◆ chan_pjsip_read_stream()

static struct ast_frame * chan_pjsip_read_stream ( struct ast_channel ast)
static

Function called by core to read any waiting frames.

Note
The channel is already locked.

Definition at line 839 of file chan_pjsip.c.

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

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

◆ chan_pjsip_remove_hold()

static void chan_pjsip_remove_hold ( const char *  chan_uid)
static

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

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

Definition at line 1149 of file chan_pjsip.c.

1150{
1152}
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_UNLINK
Definition: astobj2.h:1039

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

Referenced by chan_pjsip_indicate(), and chan_pjsip_session_end().

◆ chan_pjsip_request()

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

Asterisk core interaction functions.

Definition at line 2736 of file chan_pjsip.c.

2737{
2738 struct ast_stream_topology *topology;
2739 struct ast_channel *chan;
2740
2742 if (!topology) {
2743 return NULL;
2744 }
2745
2746 chan = chan_pjsip_request_with_stream_topology(type, topology, assignedids, requestor, data, cause);
2747
2748 ast_stream_topology_free(topology);
2749
2750 return chan;
2751}
static const char type[]
Definition: chan_ooh323.c:109
static struct ast_channel * chan_pjsip_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Function called by core to create a new outgoing PJSIP session.
Definition: chan_pjsip.c:2709
struct ast_stream_topology * ast_stream_topology_create_from_format_cap(struct ast_format_cap *cap)
A helper function that, given a format capabilities structure, creates a topology and separates the m...
Definition: stream.c:848
const char * data

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

◆ chan_pjsip_request_with_stream_topology()

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

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

Definition at line 2709 of file chan_pjsip.c.

2710{
2711 struct request_data req_data;
2713 SCOPE_ENTER(1, "%s Topology: %s\n", data,
2715
2716 req_data.topology = topology;
2717 req_data.dest = data;
2718 /* Default failure value in case ast_sip_push_task_wait_servant() itself fails. */
2719 req_data.cause = AST_CAUSE_FAILURE;
2720
2721 if (ast_sip_push_task_wait_servant(NULL, request, &req_data)) {
2722 *cause = req_data.cause;
2723 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't push task\n");
2724 }
2725
2726 session = req_data.session;
2727
2728 if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
2729 /* Session needs to be terminated prematurely */
2730 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
2731 }
2732
2733 SCOPE_EXIT_RTN_VALUE(session->channel, "Channel: %s\n", ast_channel_name(session->channel));
2734}
#define AST_CAUSE_FAILURE
Definition: causes.h:150
static int request(void *obj)
Definition: chan_pjsip.c:2601
@ AST_STATE_DOWN
Definition: channelstate.h:36
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:2165
struct ast_stream_topology * topology
Definition: chan_pjsip.c:2596

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

Referenced by chan_pjsip_request().

◆ chan_pjsip_sendtext()

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

Definition at line 2879 of file chan_pjsip.c.

2880{
2881 struct ast_msg_data *msg;
2882 int rc;
2883 struct ast_msg_data_attribute attrs[] =
2884 {
2885 {
2887 .value = (char *)text,
2888 }
2889 };
2890
2892 if (!msg) {
2893 return -1;
2894 }
2895 rc = chan_pjsip_sendtext_data(ast, msg);
2896 ast_free(msg);
2897
2898 return rc;
2899}
char * text
Definition: app_queue.c:1639
#define ast_free(a)
Definition: astmm.h:180
static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg)
Function called by core to send text on PJSIP session.
Definition: chan_pjsip.c:2857
struct ast_msg_data * ast_msg_data_alloc(enum ast_msg_data_source_type source, struct ast_msg_data_attribute attributes[], size_t count)
Allocates an ast_msg_data structure.
@ AST_MSG_DATA_ATTR_BODY
Definition: message.h:458
@ AST_MSG_DATA_SOURCE_TYPE_UNKNOWN
Definition: message.h:447
enum ast_msg_data_attribute_type type
Definition: message.h:463
Structure used to transport a message through the frame core.
#define ARRAY_LEN(a)
Definition: utils.h:666

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

◆ chan_pjsip_sendtext_data()

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

Function called by core to send text on PJSIP session.

Definition at line 2857 of file chan_pjsip.c.

2858{
2859 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2860 struct sendtext_data *data = sendtext_data_create(ast, msg);
2861
2862 ast_debug(1, "Sending MESSAGE from '%s' to '%s:%s': %s\n",
2865 ast_channel_name(ast),
2867
2868 if (!data) {
2869 return -1;
2870 }
2871
2872 if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
2873 ao2_ref(data, -1);
2874 return -1;
2875 }
2876 return 0;
2877}
static int sendtext(void *obj)
Definition: chan_pjsip.c:2786
static struct sendtext_data * sendtext_data_create(struct ast_channel *chan, struct ast_msg_data *msg)
Definition: chan_pjsip.c:2765
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
@ AST_MSG_DATA_ATTR_TO
Definition: message.h:455
@ AST_MSG_DATA_ATTR_FROM
Definition: message.h:456
struct ast_msg_data * msg
Definition: chan_pjsip.c:2755

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

Referenced by chan_pjsip_sendtext().

◆ chan_pjsip_session_begin()

static void chan_pjsip_session_begin ( struct ast_sip_session session)
static

SIP session interaction functions.

Definition at line 2901 of file chan_pjsip.c.

2902{
2903 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
2905
2906 if (session->endpoint->media.direct_media.glare_mitigation ==
2908 SCOPE_EXIT_RTN("Direct media no glare mitigation\n");
2909 }
2910
2912 "direct_media_glare_mitigation");
2913
2914 if (!datastore) {
2915 SCOPE_EXIT_RTN("Couldn't create datastore\n");
2916 }
2917
2920}
static struct ast_datastore_info direct_media_mitigation_info
Definition: chan_pjsip.c:274
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE
Definition: res_pjsip.h:634

References ao2_cleanup, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_name(), direct_media_mitigation_info, NULL, RAII_VAR, SCOPE_ENTER, SCOPE_EXIT_RTN, and session.

◆ chan_pjsip_session_end()

static void chan_pjsip_session_end ( struct ast_sip_session session)
static

Function called when the session ends.

Definition at line 2923 of file chan_pjsip.c.

2924{
2926
2927 if (!session->channel) {
2928 SCOPE_EXIT_RTN("No channel\n");
2929 }
2930
2931
2932 if (session->active_media_state &&
2933 session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
2934 struct ast_sip_session_media *media =
2935 session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
2936 if (media->rtp) {
2938 }
2939 }
2940
2942
2943 ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2944 if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
2945 int cause = ast_sip_hangup_sip2cause(session->inv_session->cause);
2946
2947 ast_queue_hangup_with_cause(session->channel, cause);
2948 } else {
2949 ast_queue_hangup(session->channel);
2950 }
2951
2953}
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_instance *instance)
Set standard statistics from an RTP instance on a channel.
Definition: rtp_engine.c:2528

References ast_channel_hangupcause(), ast_channel_name(), ast_channel_uniqueid(), AST_MEDIA_TYPE_AUDIO, ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_sip_hangup_sip2cause(), ast_sip_session_get_name(), chan_pjsip_remove_hold(), ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN, and session.

◆ chan_pjsip_set_rtp_peer()

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

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

Definition at line 448 of file chan_pjsip.c.

454{
455 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
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
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}
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
static int send_direct_media_request(void *data)
Definition: chan_pjsip.c:396
static int cdata(void *userdata, int state, const char *cdata, size_t len)
struct ast_rtp_instance * vrtp
Definition: chan_pjsip.c:361
struct ast_channel * chan
Definition: chan_pjsip.c:359
struct ast_rtp_instance * rtp
Definition: chan_pjsip.c:360
struct ast_format_cap * cap
Definition: chan_pjsip.c:362

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, rtp_direct_media_data::cap, cdata(), rtp_direct_media_data::chan, ast_sip_session::channel, LOG_ERROR, rtp_direct_media_data::rtp, rtp_direct_media_data_create(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, send_direct_media_request(), session, and rtp_direct_media_data::vrtp.

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

2165{
2166 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2167 struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
2168
2169 if (!trnf_data) {
2170 return -1;
2171 }
2172
2173 if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
2174 ast_log(LOG_WARNING, "Error requesting transfer\n");
2175 ao2_cleanup(trnf_data);
2176 return -1;
2177 }
2178
2179 return 0;
2180}
static int transfer(void *data)
Definition: chan_pjsip.c:2129
static struct transfer_data * transfer_data_alloc(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1891

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

◆ chan_pjsip_write()

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

Definition at line 1040 of file chan_pjsip.c.

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

References chan_pjsip_write_stream().

◆ chan_pjsip_write_stream()

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

Definition at line 950 of file chan_pjsip.c.

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

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

Referenced by chan_pjsip_write().

◆ check_for_rtp_changes()

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

Definition at line 327 of file chan_pjsip.c.

329{
330 int changed = 0, position = -1;
331
332 if (media->rtp) {
333 position = rtp_find_rtcp_fd_position(session, media->rtp);
334 }
335
336 if (rtp) {
338 if (media->rtp) {
339 if (position != -1) {
340 ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, -1);
341 }
343 }
344 } else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
346 changed = 1;
347 if (media->rtp) {
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}
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:306
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
#define ast_rtp_instance_get_and_cmp_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to, comparing its address to another.
Definition: rtp_engine.h:1274
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:726
@ AST_RTP_PROPERTY_RTCP
Definition: rtp_engine.h:123
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2205
struct ast_sockaddr direct_media_addr
Direct media address.

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

Referenced by send_direct_media_request().

◆ clear_session_and_channel()

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

Clear a channel from a session along with its PVT.

Definition at line 2509 of file chan_pjsip.c.

2510{
2511 session->channel = NULL;
2514}

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

Referenced by chan_pjsip_hangup(), and hangup().

◆ compatible_formats_exist()

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

Determine if a topology is compatible with format capabilities.

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

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

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

Definition at line 526 of file chan_pjsip.c.

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}
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition: format_cap.c:653

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

Referenced by chan_pjsip_new().

◆ direct_media_mitigate_glare()

static int direct_media_mitigate_glare ( struct ast_sip_session session)
static

Definition at line 276 of file chan_pjsip.c.

277{
278 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
279
280 if (session->endpoint->media.direct_media.glare_mitigation ==
282 return 0;
283 }
284
285 datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
286 if (!datastore) {
287 return 0;
288 }
289
290 /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
291 ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
292
293 if ((session->endpoint->media.direct_media.glare_mitigation ==
295 session->inv_session->role == PJSIP_ROLE_UAC) ||
296 (session->endpoint->media.direct_media.glare_mitigation ==
298 session->inv_session->role == PJSIP_ROLE_UAS)) {
299 return 1;
300 }
301
302 return 0;
303}
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING
Definition: res_pjsip.h:642
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING
Definition: res_pjsip.h:638
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.

References ao2_cleanup, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING, ast_sip_session_get_datastore(), ast_sip_session_remove_datastore(), NULL, RAII_VAR, and session.

Referenced by send_direct_media_request().

◆ handle_topology_request_change()

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

Definition at line 1597 of file chan_pjsip.c.

1599{
1601 int res;
1602 SCOPE_ENTER(1);
1603
1605 if (!refresh_data) {
1606 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create refresh_data\n");
1607 }
1608
1610 if (res) {
1612 }
1613 SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
1614}
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:1520
static int send_topology_change_refresh(void *data)
Definition: chan_pjsip.c:1571
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
Definition: chan_pjsip.c:1512

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

Referenced by chan_pjsip_indicate().

◆ hangup()

static int hangup ( void *  data)
static

Definition at line 2516 of file chan_pjsip.c.

2517{
2518 struct hangup_data *h_data = data;
2519 struct ast_channel *ast = h_data->chan;
2520 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2521 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2522
2523 /*
2524 * Before cleaning we have to ensure that channel or its session is not NULL
2525 * we have seen rare case when taskprocessor calls hangup but channel is NULL
2526 * due to SIP session timeout and answer happening at the same time
2527 */
2528 if (channel) {
2529 struct ast_sip_session *session = channel->session;
2530 if (session) {
2531 int cause = h_data->cause;
2532
2533 if (channel->session->active_media_state &&
2534 channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
2535 struct ast_sip_session_media *media =
2537 if (media->rtp) {
2539 }
2540 }
2541
2542 /*
2543 * It's possible that session_terminate might cause the session to be destroyed
2544 * immediately so we need to keep a reference to it so we can NULL session->channel
2545 * afterwards.
2546 */
2550 }
2551 ao2_cleanup(channel);
2552 }
2553 ao2_cleanup(h_data);
2555}
struct ast_channel * chan
Definition: chan_pjsip.c:2484

References ast_sip_session::active_media_state, ao2_bump, ao2_cleanup, ast_channel_name(), ast_channel_tech_pvt(), AST_MEDIA_TYPE_AUDIO, ast_rtp_instance_set_stats_vars(), ast_sip_session_terminate(), hangup_data::cause, hangup_data::chan, ast_sip_session::channel, clear_session_and_channel(), ast_sip_session_media_state::default_session, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, ast_sip_channel_pvt::session, and session.

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

◆ hangup_cause2sip()

static int hangup_cause2sip ( int  cause)
static

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

Definition at line 2435 of file chan_pjsip.c.

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

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

Referenced by chan_pjsip_hangup().

◆ hangup_data_alloc()

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

Definition at line 2494 of file chan_pjsip.c.

2495{
2496 struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
2497
2498 if (!h_data) {
2499 return NULL;
2500 }
2501
2502 h_data->cause = cause;
2503 h_data->chan = ast_channel_ref(chan);
2504
2505 return h_data;
2506}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void hangup_data_destroy(void *obj)
Definition: chan_pjsip.c:2487

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

Referenced by chan_pjsip_hangup().

◆ hangup_data_destroy()

static void hangup_data_destroy ( void *  obj)
static

Definition at line 2487 of file chan_pjsip.c.

2488{
2489 struct hangup_data *h_data = obj;
2490
2491 h_data->chan = ast_channel_unref(h_data->chan);
2492}

References ast_channel_unref, and hangup_data::chan.

Referenced by hangup_data_alloc().

◆ indicate()

static int indicate ( void *  data)
static

Definition at line 1334 of file chan_pjsip.c.

1335{
1336 pjsip_tx_data *packet = NULL;
1337 struct indicate_data *ind_data = data;
1338 struct ast_sip_session *session = ind_data->session;
1339 int response_code = ind_data->response_code;
1340
1341 if ((session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
1342 (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
1344 }
1345
1346 ao2_ref(ind_data, -1);
1347
1348 return 0;
1349}
struct ast_sip_session * session
Definition: chan_pjsip.c:1294

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

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

◆ indicate_data_alloc()

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

Definition at line 1309 of file chan_pjsip.c.

1311{
1312 struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
1313
1314 if (!ind_data) {
1315 return NULL;
1316 }
1317
1318 ind_data->frame_data = ast_malloc(datalen);
1319 if (!ind_data->frame_data) {
1320 ao2_ref(ind_data, -1);
1321 return NULL;
1322 }
1323
1324 memcpy(ind_data->frame_data, frame_data, datalen);
1325 ind_data->datalen = datalen;
1326 ind_data->condition = condition;
1327 ind_data->response_code = response_code;
1328 ao2_ref(session, +1);
1329 ind_data->session = session;
1330
1331 return ind_data;
1332}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
static void indicate_data_destroy(void *obj)
Definition: chan_pjsip.c:1301
void * frame_data
Definition: chan_pjsip.c:1297

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

Referenced by chan_pjsip_indicate().

◆ indicate_data_destroy()

static void indicate_data_destroy ( void *  obj)
static

Definition at line 1301 of file chan_pjsip.c.

1302{
1303 struct indicate_data *ind_data = obj;
1304
1305 ast_free(ind_data->frame_data);
1306 ao2_ref(ind_data->session, -1);
1307}

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

Referenced by indicate_data_alloc().

◆ info_dtmf_data_alloc()

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

Definition at line 2238 of file chan_pjsip.c.

2239{
2240 struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
2241 if (!dtmf_data) {
2242 return NULL;
2243 }
2244 ao2_ref(session, +1);
2245 dtmf_data->session = session;
2246 dtmf_data->digit = digit;
2247 dtmf_data->duration = duration;
2248 return dtmf_data;
2249}
static void info_dtmf_data_destroy(void *obj)
Definition: chan_pjsip.c:2232
struct ast_sip_session * session
Definition: chan_pjsip.c:2227

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

Referenced by chan_pjsip_digit_end(), and chan_pjsip_indicate().

◆ info_dtmf_data_destroy()

static void info_dtmf_data_destroy ( void *  obj)
static

Definition at line 2232 of file chan_pjsip.c.

2233{
2234 struct info_dtmf_data *dtmf_data = obj;
2235 ao2_ref(dtmf_data->session, -1);
2236}

References ao2_ref, and info_dtmf_data::session.

Referenced by info_dtmf_data_alloc().

◆ is_colp_update_allowed()

static int is_colp_update_allowed ( struct ast_sip_session session)
static

Definition at line 1403 of file chan_pjsip.c.

1404{
1405 struct ast_party_id connected_id;
1406 int update_allowed = 0;
1407
1408 if (!session->endpoint->id.send_connected_line
1409 || (!session->endpoint->id.send_pai && !session->endpoint->id.send_rpid)) {
1410 return 0;
1411 }
1412
1413 /*
1414 * Check if privacy allows the update. Check while the channel
1415 * is locked so we can work with the shallow connected_id copy.
1416 */
1417 ast_channel_lock(session->channel);
1418 connected_id = ast_channel_connected_effective_id(session->channel);
1419 if (connected_id.number.valid
1420 && (session->endpoint->id.trust_outbound
1422 update_allowed = 1;
1423 }
1424 ast_channel_unlock(session->channel);
1425
1426 return update_allowed;
1427}
#define AST_PRES_ALLOWED
Definition: callerid.h:418
#define AST_PRES_RESTRICTION
Definition: callerid.h:417
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_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
Information needed to identify an endpoint in a call.
Definition: channel.h:338

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

Referenced by update_connected_line_information().

◆ is_compatible_format()

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

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

Definition at line 825 of file chan_pjsip.c.

826{
827 struct ast_stream_topology *topology = session->active_media_state->topology;
828 struct ast_stream *stream = ast_stream_topology_get_stream(topology, f->stream_num);
829 const struct ast_format_cap *cap = ast_stream_get_formats(stream);
830
832}
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330

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

Referenced by chan_pjsip_read_stream().

◆ load_module()

static int load_module ( void  )
static

Load the module.

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

Definition at line 3281 of file chan_pjsip.c.

3282{
3283 struct ao2_container *endpoints;
3284
3287 }
3288
3290
3292
3294 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
3295 goto end;
3296 }
3297
3299 ast_log(LOG_ERROR, "Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
3300 goto end;
3301 }
3302
3304 ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI dialplan function\n");
3305 goto end;
3306 }
3307
3309 ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
3310 goto end;
3311 }
3312
3314 ast_log(LOG_WARNING, "Unable to register PJSIP_DTMF_MODE dialplan function\n");
3315 goto end;
3316 }
3317
3319 ast_log(LOG_WARNING, "Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
3320 goto end;
3321 }
3322
3324 ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
3325 goto end;
3326 }
3327
3329 ast_log(LOG_WARNING, "Unable to register PJSIPHangup dialplan application\n");
3330 goto end;
3331 }
3333
3334
3336
3339
3343 ast_log(LOG_ERROR, "Unable to create held channels container\n");
3344 goto end;
3345 }
3346
3351
3353 ast_log(LOG_ERROR, "Unable to register PJSIP Channel CLI\n");
3354 goto end;
3355 }
3356
3357 /* since endpoints are loaded before the channel driver their device
3358 states get set to 'invalid', so they need to be updated */
3359 if ((endpoints = ast_sip_get_endpoints())) {
3361 ao2_ref(endpoints, -1);
3362 }
3363
3364 return 0;
3365
3366end:
3384
3387
3389}
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition: astobj2.h:365
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
Definition: astobj2.h:1188
static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
Definition: chan_pjsip.c:1085
static char * app_pjsip_hangup
Definition: chan_pjsip.c:3269
static int update_devstate(void *obj, void *arg, int flags)
Definition: chan_pjsip.c:3229
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
Definition: chan_pjsip.c:143
static struct ast_custom_function chan_pjsip_dial_contacts_function
Definition: chan_pjsip.c:3236
static int uid_hold_hash_fn(const void *obj, const int flags)
Definition: chan_pjsip.c:1067
static struct ast_sip_session_supplement pbx_start_supplement
Definition: chan_pjsip.c:3110
static struct ast_sip_session_supplement chan_pjsip_prack_supplement
Definition: chan_pjsip.c:172
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
Definition: chan_pjsip.c:486
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1948
static const char channel_type[]
Definition: chan_pjsip.c:78
static struct ast_custom_function moh_passthrough_function
Definition: chan_pjsip.c:3258
static struct ast_custom_function media_offer_function
Definition: chan_pjsip.c:3246
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
Definition: chan_pjsip.c:164
static struct ast_custom_function chan_pjsip_parse_uri_function
Definition: chan_pjsip.c:3241
static struct ast_custom_function session_refresh_function
Definition: chan_pjsip.c:3264
static struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Definition: chan_pjsip.c:155
static struct ast_sip_session_supplement call_pickup_supplement
Definition: chan_pjsip.c:3070
static struct ast_custom_function dtmf_mode_function
Definition: chan_pjsip.c:3252
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
Definition: cli_commands.c:462
int pjsip_app_hangup(struct ast_channel *chan, const char *data)
PJSIPHangup Dialplan App.
int pjsip_action_hangup(struct mansession *s, const struct message *m)
PJSIPHangup Manager Action.
char * end
Definition: eagi_proxy.c:73
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8041
static struct ao2_container * endpoints
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
#define EVENT_FLAG_CALL
Definition: manager.h:76
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:133
struct ao2_container * ast_sip_get_endpoints(void)
Retrieve any endpoints available to sorcery.
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:117
#define ast_sip_session_register_supplement(supplement)
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
Definition: pjsip_session.c:63
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:893
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:407
Generic container type.
struct ast_format_cap * capabilities
Definition: channel.h:632

References AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_callback, ao2_cleanup, ao2_container_alloc_hash, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_ref, app_pjsip_hangup, 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_manager_register_xml, ast_manager_unregister(), AST_MEDIA_TYPE_AUDIO, AST_MODULE_LOAD_DECLINE, ast_register_application_xml, 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_unregister_application(), call_pickup_supplement, ast_channel_tech::capabilities, chan_pjsip_ack_supplement, chan_pjsip_dial_contacts_function, chan_pjsip_parse_uri_function, chan_pjsip_prack_supplement, chan_pjsip_rtp_glue, chan_pjsip_supplement, chan_pjsip_supplement_response, chan_pjsip_tech, channel_type, dtmf_mode_function, end, endpoints, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, LOG_ERROR, LOG_WARNING, media_offer_function, moh_passthrough_function, NULL, OBJ_NODATA, pbx_start_supplement, pjsip_action_hangup(), pjsip_app_hangup(), pjsip_channel_cli_register(), pjsip_uids_onhold, refer_callback_module, session_refresh_function, uid_hold_hash_fn(), uid_hold_sort_fn(), and update_devstate().

◆ on_topology_change_response()

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

Definition at line 1545 of file chan_pjsip.c.

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

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

Referenced by send_topology_change_refresh().

◆ pbx_start_incoming_request()

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

Definition at line 3076 of file chan_pjsip.c.

3077{
3078 int res;
3080
3081 /* Check for a to-tag to determine if this is a reinvite */
3082 if (rdata->msg_info.to->tag.slen) {
3083 /* We don't care about reinvites */
3084 SCOPE_EXIT_RTN_VALUE(0, "Reinvite\n");
3085 }
3086
3087 res = ast_pbx_start(session->channel);
3088
3089 switch (res) {
3090 case AST_PBX_FAILED:
3091 ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
3093 ast_hangup(session->channel);
3094 break;
3095 case AST_PBX_CALL_LIMIT:
3096 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
3098 ast_hangup(session->channel);
3099 break;
3100 case AST_PBX_SUCCESS:
3101 default:
3102 break;
3103 }
3104
3105 ast_debug(3, "Started PBX on new PJSIP channel %s\n", ast_channel_name(session->channel));
3106
3107 SCOPE_EXIT_RTN_VALUE((res == AST_PBX_SUCCESS) ? 0 : -1, "RC: %d\n", res);
3108}
@ AST_PBX_FAILED
Definition: pbx.h:372
@ AST_PBX_CALL_LIMIT
Definition: pbx.h:373
@ AST_PBX_SUCCESS
Definition: pbx.h:371
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708

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

◆ remote_send_hold()

static int remote_send_hold ( void *  data)
static

Update local hold state to be held.

Definition at line 1496 of file chan_pjsip.c.

1497{
1498 return remote_send_hold_refresh(data, 1);
1499}
static int remote_send_hold_refresh(struct ast_sip_session *session, unsigned int held)
Update local hold state and send a re-INVITE with the new SDP.
Definition: chan_pjsip.c:1483

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

◆ remote_send_hold_refresh()

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

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

Definition at line 1483 of file chan_pjsip.c.

1484{
1485 struct ast_sip_session_media *session_media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
1486 if (session_media) {
1487 session_media->locally_held = held;
1488 }
1490 ao2_ref(session, -1);
1491
1492 return 0;
1493}
@ AST_SIP_SESSION_REFRESH_METHOD_INVITE
Definition: res_pjsip.h:627
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.
unsigned int locally_held
Stream is on hold by local side.

References ao2_ref, AST_MEDIA_TYPE_AUDIO, ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, ast_sip_session_media::locally_held, NULL, and session.

Referenced by remote_send_hold(), and remote_send_unhold().

◆ remote_send_unhold()

static int remote_send_unhold ( void *  data)
static

Update local hold state to be unheld.

Definition at line 1502 of file chan_pjsip.c.

1503{
1504 return remote_send_hold_refresh(data, 0);
1505}

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

◆ request()

static int request ( void *  obj)
static

Definition at line 2601 of file chan_pjsip.c.

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

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

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

◆ rtp_direct_media_data_create()

static struct rtp_direct_media_data * rtp_direct_media_data_create ( struct ast_channel chan,
struct ast_rtp_instance rtp,
struct ast_rtp_instance vrtp,
const struct ast_format_cap cap,
struct ast_sip_session session 
)
static

Definition at line 377 of file chan_pjsip.c.

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}
static void rtp_direct_media_data_destroy(void *data)
Definition: chan_pjsip.c:366

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

Referenced by chan_pjsip_set_rtp_peer().

◆ rtp_direct_media_data_destroy()

static void rtp_direct_media_data_destroy ( void *  data)
static

Definition at line 366 of file chan_pjsip.c.

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}

References ao2_cleanup, and cdata().

Referenced by rtp_direct_media_data_create().

◆ rtp_find_rtcp_fd_position()

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

Helper function to find the position for RTCP.

Definition at line 306 of file chan_pjsip.c.

307{
308 int index;
309
310 for (index = 0; index < AST_VECTOR_SIZE(&session->active_media_state->read_callbacks); ++index) {
311 struct ast_sip_session_media_read_callback_state *callback_state =
312 AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, index);
313
314 if (callback_state->fd != ast_rtp_instance_fd(rtp, 1)) {
315 continue;
316 }
317
318 return index;
319 }
320
321 return -1;
322}

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

Referenced by check_for_rtp_changes().

◆ send_direct_media_request()

static int send_direct_media_request ( void *  data)
static

Definition at line 396 of file chan_pjsip.c.

397{
398 struct rtp_direct_media_data *cdata = data;
399 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(cdata->chan);
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;
414 if (session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
415 changed |= check_for_rtp_changes(
416 cdata->chan, cdata->rtp, session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO], session);
417 }
418 if (session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO]) {
419 changed |= check_for_rtp_changes(
420 cdata->chan, cdata->vrtp, session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO], session);
421 }
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) &&
431 !ast_format_cap_identical(cdata->session->direct_media_cap, cdata->cap)) {
433 ast_format_cap_append_from_cap(cdata->session->direct_media_cap, cdata->cap, AST_MEDIA_TYPE_UNKNOWN);
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,
440 cdata->session->endpoint->media.direct_media.method, 1, NULL);
441 }
442
443 ao2_ref(cdata, -1);
444 return res;
445}
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:327
static int direct_media_mitigate_glare(struct ast_sip_session *session)
Definition: chan_pjsip.c:276
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:687
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

References 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(), cdata(), ast_sip_session::channel, check_for_rtp_changes(), direct_media_mitigate_glare(), NULL, and session.

Referenced by chan_pjsip_set_rtp_peer().

◆ send_topology_change_refresh()

static int send_topology_change_refresh ( void *  data)
static

Definition at line 1571 of file chan_pjsip.c.

1572{
1577 int ret;
1579 ast_str_tmp(256, ast_stream_topology_to_str(refresh_data->media_state->topology, &STR_TMP)));
1580
1581 /* See RFC 6337, especially section 3.2: If the early media SDP was sent reliably, we are allowed
1582 * to send UPDATEs. Only relevant for AST_STATE_RINGING and AST_STATE_RING - if the channel is UP,
1583 * re-INVITES can be sent.
1584 */
1585 if (session->early_confirmed && (state == AST_STATE_RINGING || state == AST_STATE_RING)) {
1587 }
1588
1590 method, 1, refresh_data->media_state);
1591 refresh_data->media_state = NULL;
1593
1595}
static int on_topology_change_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
Definition: chan_pjsip.c:1545
const char * method
Definition: res_pjsip.c:1279
ast_sip_session_refresh_method
Definition: res_pjsip.h:625
@ AST_SIP_SESSION_REFRESH_METHOD_UPDATE
Definition: res_pjsip.h:629
struct ast_sip_session * session

References ast_sip_session_get_name(), ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, AST_SIP_SESSION_REFRESH_METHOD_UPDATE, AST_STATE_RING, AST_STATE_RINGING, ast_str_tmp, ast_stream_topology_to_str(), method, NULL, on_topology_change_response(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, refresh_data::session, session, and topology_change_refresh_data_free().

Referenced by handle_topology_request_change().

◆ sendtext()

static int sendtext ( void *  obj)
static

Definition at line 2786 of file chan_pjsip.c.

2787{
2788 struct sendtext_data *data = obj;
2789 pjsip_tx_data *tdata;
2790 const char *body_text = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_BODY);
2791 const char *content_type = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_CONTENT_TYPE);
2792 char *sep;
2793 struct ast_sip_body body = {
2794 .type = "text",
2795 .subtype = "plain",
2796 .body_text = body_text,
2797 };
2798
2799 if (!ast_strlen_zero(content_type)) {
2800 sep = strchr(content_type, '/');
2801 if (sep) {
2802 *sep = '\0';
2803 body.type = content_type;
2804 body.subtype = ++sep;
2805 }
2806 }
2807
2808 if (data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2809 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2810 data->session->inv_session->cause,
2811 pjsip_get_status_text(data->session->inv_session->cause)->ptr);
2812 } else {
2813 pjsip_from_hdr *hdr;
2814 pjsip_name_addr *name_addr;
2815 const char *from = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_FROM);
2816 const char *to = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_TO);
2817 int invalidate_tdata = 0;
2818
2819 ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
2820 ast_sip_add_body(tdata, &body);
2821
2822 /*
2823 * If we have a 'from' in the msg, set the display name in the From
2824 * header to it.
2825 */
2826 if (!ast_strlen_zero(from)) {
2827 hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
2828 name_addr = (pjsip_name_addr *) hdr->uri;
2829 pj_strdup2(tdata->pool, &name_addr->display, from);
2830 invalidate_tdata = 1;
2831 }
2832
2833 /*
2834 * If we have a 'to' in the msg, set the display name in the To
2835 * header to it.
2836 */
2837 if (!ast_strlen_zero(to)) {
2838 hdr = PJSIP_MSG_TO_HDR(tdata->msg);
2839 name_addr = (pjsip_name_addr *) hdr->uri;
2840 pj_strdup2(tdata->pool, &name_addr->display, to);
2841 invalidate_tdata = 1;
2842 }
2843
2844 if (invalidate_tdata) {
2845 pjsip_tx_data_invalidate_msg(tdata);
2846 }
2847
2848 ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
2849 }
2850
2851 ao2_cleanup(data);
2852
2853 return 0;
2854}
@ AST_MSG_DATA_ATTR_CONTENT_TYPE
Definition: message.h:457
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:1979
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:2052
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:1435
SIP body description.
Definition: res_pjsip.h:2325
const char * type
Definition: res_pjsip.h:2327
const char * body_text
Definition: res_pjsip.h:2331
const char * subtype
Definition: res_pjsip.h:2329
struct ast_sip_session * session
Definition: chan_pjsip.c:2754

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

◆ sendtext_data_create()

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

Definition at line 2765 of file chan_pjsip.c.

2767{
2768 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2769 struct sendtext_data *data = ao2_alloc(sizeof(*data), sendtext_data_destroy);
2770
2771 if (!data) {
2772 return NULL;
2773 }
2774
2775 data->msg = ast_msg_data_dup(msg);
2776 if (!data->msg) {
2777 ao2_cleanup(data);
2778 return NULL;
2779 }
2780 data->session = channel->session;
2781 ao2_ref(data->session, +1);
2782
2783 return data;
2784}
static void sendtext_data_destroy(void *obj)
Definition: chan_pjsip.c:2758
struct ast_msg_data * ast_msg_data_dup(struct ast_msg_data *msg)
Clone an ast_msg_data structure.

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

Referenced by chan_pjsip_sendtext_data().

◆ sendtext_data_destroy()

static void sendtext_data_destroy ( void *  obj)
static

Definition at line 2758 of file chan_pjsip.c.

2759{
2760 struct sendtext_data *data = obj;
2761 ao2_cleanup(data->session);
2762 ast_free(data->msg);
2763}

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

Referenced by sendtext_data_create().

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

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:574

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

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

◆ set_sipdomain_variable()

static void set_sipdomain_variable ( struct ast_sip_session session)
static

Definition at line 2955 of file chan_pjsip.c.

2956{
2957 const pj_str_t *host = ast_sip_pjsip_uri_get_hostname(session->request_uri);
2958 size_t size = pj_strlen(host) + 1;
2959 char *domain = ast_alloca(size);
2960
2961 ast_copy_pj_str(domain, host, size);
2962
2963 pbx_builtin_setvar_helper(session->channel, "SIPDOMAIN", domain);
2964 return;
2965}
const pj_str_t * ast_sip_pjsip_uri_get_hostname(pjsip_uri *uri)
Get the host portion of the pjsip_uri.
Definition: res_pjsip.c:3496

References ast_alloca, ast_copy_pj_str(), ast_sip_pjsip_uri_get_hostname(), pbx_builtin_setvar_helper(), and session.

Referenced by chan_pjsip_incoming_request().

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

1522{
1524
1525 refresh_data = ast_calloc(1, sizeof(*refresh_data));
1526 if (!refresh_data) {
1527 return NULL;
1528 }
1529
1532 if (!refresh_data->media_state) {
1534 return NULL;
1535 }
1536 refresh_data->media_state->topology = ast_stream_topology_clone(topology);
1537 if (!refresh_data->media_state->topology) {
1539 return NULL;
1540 }
1541
1542 return refresh_data;
1543}
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.

References ao2_bump, ast_calloc, ast_sip_session_media_state_alloc(), ast_stream_topology_clone(), NULL, refresh_data::session, session, and topology_change_refresh_data_free().

Referenced by handle_topology_request_change().

◆ topology_change_refresh_data_free()

static void topology_change_refresh_data_free ( struct topology_change_refresh_data refresh_data)
static

Definition at line 1512 of file chan_pjsip.c.

1513{
1515
1518}
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.

References ao2_cleanup, ast_free, ast_sip_session_media_state_free(), and refresh_data::session.

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

◆ transfer()

static int transfer ( void *  data)
static

Definition at line 2129 of file chan_pjsip.c.

2130{
2131 struct transfer_data *trnf_data = data;
2132 struct ast_sip_endpoint *endpoint = NULL;
2133 struct ast_sip_contact *contact = NULL;
2134 const char *target = trnf_data->target;
2135
2136 if (trnf_data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2137 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2138 trnf_data->session->inv_session->cause,
2139 pjsip_get_status_text(trnf_data->session->inv_session->cause)->ptr);
2140 } else {
2141 /* See if we have an endpoint; if so, use its contact */
2143 if (endpoint) {
2145 if (contact && !ast_strlen_zero(contact->uri)) {
2146 target = contact->uri;
2147 }
2148 }
2149
2150 if (ast_channel_state(trnf_data->session->channel) == AST_STATE_RING) {
2151 transfer_redirect(trnf_data->session, target);
2152 } else {
2153 transfer_refer(trnf_data->session, target);
2154 }
2155 }
2156
2157 ao2_ref(trnf_data, -1);
2159 ao2_cleanup(contact);
2160 return 0;
2161}
static void transfer_redirect(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1910
static void transfer_refer(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:2077
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
Contact associated with an address of record.
Definition: res_pjsip.h:392
const ast_string_field uri
Definition: res_pjsip.h:414
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.h:424
const ast_string_field aors
Definition: res_pjsip.h:992
struct ast_sip_session * session
Definition: chan_pjsip.c:1879

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_contact::endpoint, 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 __send_command(), ast_transfer_protocol(), chan_pjsip_transfer(), iax2_send(), leave_voicemail(), send_packet(), and transfer_exec().

◆ transfer_data_alloc()

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

Definition at line 1891 of file chan_pjsip.c.

1892{
1893 struct transfer_data *trnf_data = ao2_alloc(sizeof(*trnf_data), transfer_data_destroy);
1894
1895 if (!trnf_data) {
1896 return NULL;
1897 }
1898
1899 if (!(trnf_data->target = ast_strdup(target))) {
1900 ao2_ref(trnf_data, -1);
1901 return NULL;
1902 }
1903
1904 ao2_ref(session, +1);
1905 trnf_data->session = session;
1906
1907 return trnf_data;
1908}
static void transfer_data_destroy(void *obj)
Definition: chan_pjsip.c:1883

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

Referenced by chan_pjsip_transfer().

◆ transfer_data_destroy()

static void transfer_data_destroy ( void *  obj)
static

Definition at line 1883 of file chan_pjsip.c.

1884{
1885 struct transfer_data *trnf_data = obj;
1886
1887 ast_free(trnf_data->target);
1888 ao2_cleanup(trnf_data->session);
1889}

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

Referenced by transfer_data_alloc().

◆ transfer_redirect()

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

Definition at line 1910 of file chan_pjsip.c.

1911{
1912 pjsip_tx_data *packet;
1914 pjsip_contact_hdr *contact;
1915 pj_str_t tmp;
1916
1917 if (pjsip_inv_end_session(session->inv_session, 302, NULL, &packet) != PJ_SUCCESS
1918 || !packet) {
1919 ast_log(LOG_WARNING, "Failed to redirect PJSIP session for channel %s\n",
1920 ast_channel_name(session->channel));
1923
1924 return;
1925 }
1926
1927 if (!(contact = pjsip_msg_find_hdr(packet->msg, PJSIP_H_CONTACT, NULL))) {
1928 contact = pjsip_contact_hdr_create(packet->pool);
1929 }
1930
1931 pj_strdup2_with_null(packet->pool, &tmp, target);
1932 if (!(contact->uri = pjsip_parse_uri(packet->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR))) {
1933 ast_log(LOG_WARNING, "Failed to parse destination URI '%s' for channel %s\n",
1934 target, ast_channel_name(session->channel));
1937 pjsip_tx_data_dec_ref(packet);
1938
1939 return;
1940 }
1941 pjsip_msg_add_hdr(packet->msg, (pjsip_hdr *) contact);
1942
1945}
ast_control_transfer
@ AST_TRANSFER_FAILED
@ AST_TRANSFER_SUCCESS
@ AST_CONTROL_TRANSFER

References ast_channel_name(), AST_CONTROL_TRANSFER, ast_log, ast_queue_control_data(), ast_sip_session_send_response(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, LOG_WARNING, NULL, session, transfer_data::target, and tmp().

Referenced by transfer().

◆ transfer_refer()

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

Definition at line 2077 of file chan_pjsip.c.

2078{
2079 pjsip_evsub *sub;
2081 pj_str_t tmp;
2082 pjsip_tx_data *packet;
2083 const char *ref_by_val;
2084 char local_info[pj_strlen(&session->inv_session->dlg->local.info_str) + 1];
2085 struct pjsip_evsub_user xfer_cb;
2086 struct ast_channel *chan = session->channel;
2087
2088 pj_bzero(&xfer_cb, sizeof(xfer_cb));
2089 xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
2090
2091 if (pjsip_xfer_create_uac(session->inv_session->dlg, &xfer_cb, &sub) != PJ_SUCCESS) {
2094
2095 return;
2096 }
2097
2098 /* refer_callback_module requires a reference to chan
2099 * which will be released in xfer_client_on_evsub_state()
2100 * when the implicit REFER subscription terminates */
2101 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, chan);
2102 ao2_ref(chan, +1);
2103
2104 if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {
2105 goto failure;
2106 }
2107
2108 ref_by_val = pbx_builtin_getvar_helper(chan, "SIPREFERREDBYHDR");
2109 if (!ast_strlen_zero(ref_by_val)) {
2110 ast_sip_add_header(packet, "Referred-By", ref_by_val);
2111 } else {
2112 ast_copy_pj_str(local_info, &session->inv_session->dlg->local.info_str, sizeof(local_info));
2113 ast_sip_add_header(packet, "Referred-By", local_info);
2114 }
2115
2116 if (pjsip_xfer_send_request(sub, packet) == PJ_SUCCESS) {
2117 return;
2118 }
2119
2120failure:
2123 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2124 pjsip_evsub_terminate(sub, PJ_FALSE);
2125
2126 ao2_ref(chan, -1);
2127}
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:1960
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct stasis_forward * sub
Definition: res_corosync.c:240
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:2008

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, NULL, pbx_builtin_getvar_helper(), refer_callback_module, session, sub, tmp(), and xfer_client_on_evsub_state().

Referenced by transfer().

◆ transmit_info_dtmf()

static int transmit_info_dtmf ( void *  data)
static

Definition at line 2251 of file chan_pjsip.c.

2252{
2253 RAII_VAR(struct info_dtmf_data *, dtmf_data, data, ao2_cleanup);
2254
2255 struct ast_sip_session *session = dtmf_data->session;
2256 struct pjsip_tx_data *tdata;
2257
2258 RAII_VAR(struct ast_str *, body_text, NULL, ast_free_ptr);
2259
2260 struct ast_sip_body body = {
2261 .type = "application",
2262 .subtype = "dtmf-relay",
2263 };
2264
2265 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2266 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2267 session->inv_session->cause,
2268 pjsip_get_status_text(session->inv_session->cause)->ptr);
2269 return -1;
2270 }
2271
2272 if (!(body_text = ast_str_create(32))) {
2273 ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
2274 return -1;
2275 }
2276 ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
2277
2279
2280 if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
2281 ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
2282 return -1;
2283 }
2284 if (ast_sip_add_body(tdata, &body)) {
2285 ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
2286 pjsip_tx_data_dec_ref(tdata);
2287 return -1;
2288 }
2290
2291 return 0;
2292}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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:1113

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, LOG_ERROR, NULL, RAII_VAR, session, and ast_sip_body::type.

Referenced by chan_pjsip_digit_end(), and chan_pjsip_indicate().

◆ transmit_info_with_vidupdate()

static int transmit_info_with_vidupdate ( void *  data)
static

Send SIP INFO with video update request.

Definition at line 1352 of file chan_pjsip.c.

1353{
1354 const char * xml =
1355 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
1356 " <media_control>\r\n"
1357 " <vc_primitive>\r\n"
1358 " <to_encoder>\r\n"
1359 " <picture_fast_update/>\r\n"
1360 " </to_encoder>\r\n"
1361 " </vc_primitive>\r\n"
1362 " </media_control>\r\n";
1363
1364 const struct ast_sip_body body = {
1365 .type = "application",
1366 .subtype = "media_control+xml",
1367 .body_text = xml
1368 };
1369
1370 RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
1371 struct pjsip_tx_data *tdata;
1372
1373 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1374 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1375 session->inv_session->cause,
1376 pjsip_get_status_text(session->inv_session->cause)->ptr);
1377 return -1;
1378 }
1379
1380 if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
1381 ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
1382 return -1;
1383 }
1384 if (ast_sip_add_body(tdata, &body)) {
1385 ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
1386 return -1;
1387 }
1389
1390 return 0;
1391}

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

Referenced by chan_pjsip_indicate().

◆ transport_info_destroy()

static void transport_info_destroy ( void *  obj)
static

Destructor function for transport_info_data.

Definition at line 261 of file chan_pjsip.c.

262{
263 struct transport_info_data *data = obj;
264 ast_free(data);
265}

References ast_free.

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

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

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

Referenced by load_module().

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

1086{
1087 const char *left = obj_left;
1088 const char *right = obj_right;
1089 int cmp;
1090
1091 switch (flags & OBJ_SEARCH_MASK) {
1092 case OBJ_SEARCH_OBJECT:
1093 case OBJ_SEARCH_KEY:
1094 cmp = strcmp(left, right);
1095 break;
1097 cmp = strncmp(left, right, strlen(right));
1098 break;
1099 default:
1100 /* Sort can only work on something with a full or partial key. */
1101 ast_assert(0);
1102 cmp = 0;
1103 break;
1104 }
1105 return cmp;
1106}
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116

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

Referenced by load_module().

◆ unload_module()

static int unload_module ( void  )
static

Unload the PJSIP channel from Asterisk.

Definition at line 3392 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, app_pjsip_hangup, ast_channel_unregister(), ast_custom_function_unregister(), ast_manager_unregister(), ast_rtp_glue_unregister(), ast_sip_session_unregister_supplement(), ast_sip_unregister_service(), ast_unregister_application(), call_pickup_supplement, ast_channel_tech::capabilities, chan_pjsip_ack_supplement, chan_pjsip_dial_contacts_function, chan_pjsip_parse_uri_function, chan_pjsip_prack_supplement, chan_pjsip_rtp_glue, chan_pjsip_supplement, chan_pjsip_supplement_response, chan_pjsip_tech, dtmf_mode_function, media_offer_function, moh_passthrough_function, NULL, pbx_start_supplement, pjsip_channel_cli_unregister(), pjsip_uids_onhold, refer_callback_module, and session_refresh_function.

◆ update_connected_line_information()

static int update_connected_line_information ( void *  data)
static

Update connected line information.

Definition at line 1430 of file chan_pjsip.c.

1431{
1432 struct ast_sip_session *session = data;
1433
1434 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1435 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1436 session->inv_session->cause,
1437 pjsip_get_status_text(session->inv_session->cause)->ptr);
1438 ao2_ref(session, -1);
1439 return -1;
1440 }
1441
1442 if (ast_channel_state(session->channel) == AST_STATE_UP
1443 || session->inv_session->role == PJSIP_ROLE_UAC) {
1446 int generate_new_sdp;
1447
1448 method = session->endpoint->id.refresh_method;
1449 if (session->inv_session->options & PJSIP_INV_SUPPORT_UPDATE) {
1451 }
1452
1453 /* Only the INVITE method actually needs SDP, UPDATE can do without */
1454 generate_new_sdp = (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE);
1455
1456 ast_sip_session_refresh(session, NULL, NULL, NULL, method, generate_new_sdp, NULL);
1457 }
1458 } else if (session->endpoint->id.rpid_immediate
1459 && session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED
1461 int response_code = 0;
1462
1463 if (ast_channel_state(session->channel) == AST_STATE_RING) {
1464 response_code = !session->endpoint->inband_progress ? 180 : 183;
1465 } else if (ast_channel_state(session->channel) == AST_STATE_RINGING) {
1466 response_code = 183;
1467 }
1468
1469 if (response_code) {
1470 struct pjsip_tx_data *packet = NULL;
1471
1472 if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
1474 }
1475 }
1476 }
1477
1478 ao2_ref(session, -1);
1479 return 0;
1480}
static int is_colp_update_allowed(struct ast_sip_session *session)
Definition: chan_pjsip.c:1403

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, is_colp_update_allowed(), LOG_ERROR, method, NULL, and session.

Referenced by chan_pjsip_indicate().

◆ update_devstate()

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

◆ update_initial_connected_line()

static void update_initial_connected_line ( struct ast_sip_session session)
static

Definition at line 2366 of file chan_pjsip.c.

2367{
2369
2370 /*
2371 * Use the channel CALLERID() as the initial connected line data.
2372 * The core or a predial handler may have supplied missing values
2373 * from the session->endpoint->id.self about who we are calling.
2374 */
2375 ast_channel_lock(session->channel);
2377 ast_channel_unlock(session->channel);
2378
2379 /* Supply initial connected line information if available. */
2380 if (!session->id.number.valid && !session->id.name.valid) {
2381 return;
2382 }
2383
2385 connected.id = session->id;
2387
2389}
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
Definition: callerid.h:540
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
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:9106
char connected
Definition: eagi_proxy.c:82
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
Connected Line/Party information.
Definition: channel.h:456

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(), connected, ast_party_caller::id, NULL, and session.

Referenced by call().

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

1961{
1962 struct ast_channel *chan;
1964 int res = 0;
1965
1966 if (!event) {
1967 return;
1968 }
1969
1970 chan = pjsip_evsub_get_mod_data(sub, refer_callback_module.id);
1971 if (!chan) {
1972 return;
1973 }
1974
1975 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
1976 /* Check if subscription is suppressed and terminate and send completion code, if so. */
1977 pjsip_rx_data *rdata;
1978 pjsip_generic_string_hdr *refer_sub;
1979 const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
1980
1981 ast_debug(3, "Transfer accepted on channel %s\n", ast_channel_name(chan));
1982
1983 /* Check if response message */
1984 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1985 rdata = event->body.tsx_state.src.rdata;
1986
1987 /* Find Refer-Sub header */
1988 refer_sub = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &REFER_SUB, NULL);
1989
1990 /* Check if subscription is suppressed. If it is, the far end will not terminate it,
1991 * and the subscription will remain active until it times out. Terminating it here
1992 * eliminates the unnecessary timeout.
1993 */
1994 if (refer_sub && !pj_stricmp2(&refer_sub->hvalue, "false")) {
1995 /* Since no subscription is desired, assume that call has been transferred successfully. */
1996 /* Channel reference will be released at end of function */
1997 /* Terminate subscription. */
1998 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
1999 pjsip_evsub_terminate(sub, PJ_TRUE);
2000 res = -1;
2001 }
2002 }
2003 } else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
2004 pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
2005 /* Check for NOTIFY complete or error. */
2006 pjsip_msg *msg;
2007 pjsip_msg_body *body;
2008 pjsip_status_line status_line = { .code = 0 };
2009 pj_bool_t is_last;
2010 pj_status_t status;
2011
2012 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
2013 pjsip_rx_data *rdata;
2014
2015 rdata = event->body.tsx_state.src.rdata;
2016 msg = rdata->msg_info.msg;
2017
2018 if (msg->type == PJSIP_REQUEST_MSG) {
2019 if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
2020 body = msg->body;
2021 if (body && !pj_stricmp2(&body->content_type.type, "message")
2022 && !pj_stricmp2(&body->content_type.subtype, "sipfrag")) {
2023 pjsip_parse_status_line((char *)body->data, body->len, &status_line);
2024 }
2025 }
2026 } else {
2027 status_line.code = msg->line.status.code;
2028 status_line.reason = msg->line.status.reason;
2029 }
2030 } else {
2031 status_line.code = 500;
2032 status_line.reason = *pjsip_get_status_text(500);
2033 }
2034
2035 is_last = (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED);
2036 /* If the status code is >= 200, the subscription is finished. */
2037 if (status_line.code >= 200 || is_last) {
2038 res = -1;
2039
2040 /* If the subscription has terminated, return AST_TRANSFER_SUCCESS for 2XX.
2041 * Return AST_TRANSFER_FAILED for any code < 200.
2042 * Otherwise, return the status code.
2043 * The subscription should not terminate for any code < 200,
2044 * but if it does, that constitutes a failure. */
2045 if (status_line.code < 200) {
2047 } else if (status_line.code >= 300) {
2048 message = status_line.code;
2049 }
2050
2051 /* If subscription not terminated and subscription is finished (status code >= 200)
2052 * terminate it */
2053 if (!is_last) {
2054 pjsip_tx_data *tdata;
2055
2056 status = pjsip_evsub_initiate(sub, pjsip_get_subscribe_method(), 0, &tdata);
2057 if (status == PJ_SUCCESS) {
2058 pjsip_evsub_send_request(sub, tdata);
2059 }
2060 }
2061 /* Finished. Remove session from subscription */
2062 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2063 ast_debug(3, "Transfer channel %s completed: %d %.*s (%s)\n",
2064 ast_channel_name(chan),
2065 status_line.code,
2066 (int)status_line.reason.slen, status_line.reason.ptr,
2067 (message == AST_TRANSFER_SUCCESS) ? "Success" : "Failure");
2068 }
2069 }
2070
2071 if (res) {
2073 ao2_ref(chan, -1);
2074 }
2075}
Definition: astman.c:222

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

Referenced by transfer_refer().

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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "res_pjsip,res_pjsip_session,res_pjsip_pubsub", }
static

Definition at line 3430 of file chan_pjsip.c.

◆ app_pjsip_hangup

char* app_pjsip_hangup = "PJSIPHangup"
static

Definition at line 3269 of file chan_pjsip.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 3430 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:3026
@ AST_SIP_SUPPLEMENT_PRIORITY_LAST
Definition: res_pjsip.h:3188

Definition at line 3070 of file chan_pjsip.c.

Referenced by load_module(), and unload_module().

◆ 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:3204
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
Definition: res_pjsip.h:3186

Definition at line 164 of file chan_pjsip.c.

Referenced by load_module(), and unload_module().

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

Referenced by load_module(), and unload_module().

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

Referenced by load_module(), and unload_module().

◆ chan_pjsip_prack_supplement

struct ast_sip_session_supplement chan_pjsip_prack_supplement
static
Initial value:
= {
.method = "PRACK",
.incoming_request = chan_pjsip_incoming_prack,
}
static int chan_pjsip_incoming_prack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3217

Definition at line 172 of file chan_pjsip.c.

Referenced by load_module(), and unload_module().

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

Referenced by load_module(), and unload_module().

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

Referenced by load_module(), and unload_module().

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

Referenced by load_module(), and unload_module().

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

Referenced by chan_pjsip_new(), load_module(), and unload_module().

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

Referenced by chan_pjsip_session_begin().

◆ dtmf_mode_function

struct ast_custom_function dtmf_mode_function
static
Initial value:
= {
.name = "PJSIP_DTMF_MODE",
}
int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_DTMF_MODE function write callback.
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.

Definition at line 3252 of file chan_pjsip.c.

Referenced by load_module(), and unload_module().

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

Referenced by load_module(), and unload_module().

◆ moh_passthrough_function

struct ast_custom_function moh_passthrough_function
static
Initial value:
= {
.name = "PJSIP_MOH_PASSTHROUGH",
}
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.
int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MOH_PASSTHROUGH function write callback.

Definition at line 3258 of file chan_pjsip.c.

Referenced by load_module(), and unload_module().

◆ 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:3076

Definition at line 3110 of file chan_pjsip.c.

Referenced by load_module(), and unload_module().

◆ pjsip_uids_onhold

struct ao2_container* pjsip_uids_onhold
static

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

Referenced by load_module(), and unload_module().

◆ 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:261

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

Definition at line 269 of file chan_pjsip.c.

Referenced by chan_pjsip_incoming_request().

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