Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Functions | Variables
chan_pjsip.c File Reference

PSJIP SIP Channel Driver. More...

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

Go to the source code of this file.

Data Structures

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

Macros

#define UNIQUEID_BUFSIZE   256
 

Functions

static void __init_uniqueid_threadbuf (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static int answer (void *data)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int call (void *data)
 
static int call_pickup_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
static int chan_pjsip_add_hold (const char *chan_uid)
 Add a channel ID to the list of PJSIP channels on hold. More...
 
static int chan_pjsip_answer (struct ast_channel *ast)
 Function called by core when we should answer a PJSIP session.
 
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.
 
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.
 
static int chan_pjsip_devicestate (const char *data)
 Function called to get the device state of an endpoint.
 
static int chan_pjsip_digit_begin (struct ast_channel *chan, char digit)
 Function called by core to start a DTMF digit.
 
static int chan_pjsip_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Function called by core to stop a DTMF digit.
 
static int chan_pjsip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 Function called by core to change the underlying owner channel.
 
static void chan_pjsip_get_codec (struct ast_channel *chan, struct ast_format_cap *result)
 Function called by RTP engine to get peer capabilities.
 
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.
 
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.
 
static int chan_pjsip_hangup (struct ast_channel *ast)
 Function called by core to hang up a PJSIP session.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
static void chan_pjsip_session_begin (struct ast_sip_session *session)
 SIP session interaction functions.
 
static void chan_pjsip_session_end (struct ast_sip_session *session)
 Function called when the session ends.
 
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.
 
static int chan_pjsip_transfer (struct ast_channel *chan, const char *target)
 Function called by core for Asterisk initiated transfer.
 
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.
 
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.
 
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.
 
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.
 
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.
 
static int remote_send_unhold (void *data)
 Update local hold state to be unheld.
 
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.
 
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.
 
static void transport_info_destroy (void *obj)
 Destructor function for transport_info_data.
 
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.
 
static int update_connected_line_information (void *data)
 Update connected line information.
 
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 = "da6642af068ee5e6490c5b1d2cc1d238" , .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_from_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.
 
static struct ast_sip_session_supplement chan_pjsip_supplement
 SIP session supplement structure.
 
static struct ast_sip_session_supplement chan_pjsip_supplement_response
 SIP session supplement structure just for responses.
 
struct ast_channel_tech chan_pjsip_tech
 PBX interface structure for channel registration.
 
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.

Function Documentation

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.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_link, ast_copy_string(), OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by chan_pjsip_indicate().

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 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
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
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
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.

References OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by chan_pjsip_devicestate().

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 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#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
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.

References ast_sip_session::active_media_state, ao2_ref, ast_channel_get_up_time(), ast_channel_is_bridged(), ast_channel_set_unbridged_nolock(), ast_debug, 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_VOICE, AST_LIST_NEXT, ast_null_frame, ast_set_read_format_path(), ast_set_write_format_path(), AST_VECTOR_GET_ADDR, AST_VECTOR_SIZE, ast_sip_endpoint::asymmetric_rtp_codec, chan_pjsip_cng_tone_detected(), ast_sip_session_media_state::default_session, ast_sip_session::dsp, ast_sip_session::endpoint, ast_sip_endpoint::faxdetect_timeout, ast_frame_subclass::format, ast_frame::frametype, ast_frame_subclass::integer, is_compatible_format(), ast_sip_session_media_read_callback_state::read_callback, ast_sip_session_media_state::read_callbacks, ast_sip_session_media_read_callback_state::session, ast_sip_channel_pvt::session, ast_frame::subclass, and ast_sip_session_media::type.

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 &&
877  ast_format_cmp(ast_channel_rawwriteformat(ast), cur->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL &&
878  is_compatible_format(session, cur)) {
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",
883  ast_format_get_name(cur->subclass.format), ast_channel_name(ast),
884  ast_format_get_name(ast_channel_rawwriteformat(ast)));
885 
887  if (caps) {
888  ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(ast), AST_MEDIA_TYPE_UNKNOWN);
889  ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_AUDIO);
890  ast_format_cap_append(caps, cur->subclass.format, 0);
891  ast_channel_nativeformats_set(ast, caps);
892  ao2_ref(caps, -1);
893  }
894 
895  ast_set_write_format_path(ast, ast_channel_writeformat(ast), cur->subclass.format);
896  ast_set_read_format_path(ast, ast_channel_readformat(ast), cur->subclass.format);
897 
898  if (ast_channel_is_bridged(ast)) {
900  }
901  }
902 
903  if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), cur->subclass.format)
905  ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n",
906  ast_format_get_name(cur->subclass.format), ast_channel_name(ast));
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));
935  f = chan_pjsip_cng_tone_detected(ast, session, f);
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 }
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
struct ast_sip_endpoint * endpoint
static int is_compatible_format(struct ast_sip_session *session, struct ast_frame *f)
Determine if the given frame is in a format we've negotiated.
Definition: chan_pjsip.c:825
unsigned int asymmetric_rtp_codec
Definition: res_pjsip.h:1030
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2845
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
A structure describing a SIP session.
struct ast_frame_subclass subclass
static struct ast_frame * chan_pjsip_cng_tone_detected(struct ast_channel *ast, struct ast_sip_session *session, struct ast_frame *f)
Internal helper function called when CNG tone is detected.
Definition: chan_pjsip.c:766
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
struct ast_sip_session_media_state * active_media_state
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:581
struct ast_dsp * dsp
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1777
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
ast_sip_session_media_read_cb read_callback
The callback to invoke.
struct ast_sip_session_media * session
The media session.
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
struct ast_sip_session_media_state::@268 read_callbacks
Added read callbacks - these are whole structs and not pointers.
#define ast_debug(level,...)
Log a DEBUG message.
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
Structure which contains read callback information.
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
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_EXTENDED_FDS
Definition: channel.h:195
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
unsigned int faxdetect_timeout
Definition: res_pjsip.h:1024
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
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
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1768
struct ast_frame ast_null_frame
Definition: main/frame.c:79
enum ast_media_type type
Media type of this session media.
Data structure associated with a single frame of data.
enum ast_frame_type frametype
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_format * format
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
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.

References OBJ_NODATA, OBJ_SEARCH_KEY, and OBJ_UNLINK.

Referenced by chan_pjsip_indicate(), and chan_pjsip_session_end().

1150 {
1151  ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
1152 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
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.

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

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 }
struct ast_sockaddr direct_media_addr
Direct media address.
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define AST_EXTENDED_FDS
Definition: channel.h:195
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:2316
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
struct ast_rtp_instance * rtp
RTP instance itself.
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:727
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
#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:1281
static int compatible_formats_exist ( struct ast_stream_topology top,
struct ast_format_cap cap 
)
static

Determine if a topology is compatible with format capabilities.

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

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

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

Definition at line 526 of file chan_pjsip.c.

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

Referenced by chan_pjsip_new().

527 {
528  struct ast_format_cap *cap_from_top;
529  int res;
530  SCOPE_ENTER(1, "Topology: %s Formats: %s\n",
533 
534  cap_from_top = ast_stream_topology_get_formats(top);
535 
536  if (!cap_from_top) {
537  SCOPE_EXIT_RTN_VALUE(0, "Topology had no formats\n");
538  }
539 
540  res = ast_format_cap_iscompatible(cap_from_top, cap);
541  ao2_ref(cap_from_top, -1);
542 
543  SCOPE_EXIT_RTN_VALUE(res, "Compatible? %s\n", res ? "yes" : "no");
544 }
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
Definition: stream.c:930
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1189
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
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
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 3286 of file chan_pjsip.c.

References AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_callback, ao2_container_alloc_hash, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_ref, ast_channel_register(), ast_channel_unregister(), ast_custom_function_register, ast_custom_function_unregister(), ast_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_manager_register_xml, ast_manager_unregister(), AST_MODULE_LOAD_DECLINE, ast_register_application_xml, ast_rtp_glue_unregister(), ast_unregister_application(), ast_channel_tech::capabilities, endpoints, OBJ_NODATA, pjsip_action_hangup(), pjsip_app_hangup(), pjsip_channel_cli_register(), uid_hold_hash_fn(), and uid_hold_sort_fn().

3287 {
3288  struct ao2_container *endpoints;
3289 
3291  return AST_MODULE_LOAD_DECLINE;
3292  }
3293 
3295 
3296  ast_rtp_glue_register(&chan_pjsip_rtp_glue);
3297 
3299  ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
3300  goto end;
3301  }
3302 
3303  if (ast_custom_function_register(&chan_pjsip_dial_contacts_function)) {
3304  ast_log(LOG_ERROR, "Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
3305  goto end;
3306  }
3307 
3308  if (ast_custom_function_register(&chan_pjsip_parse_uri_function)) {
3309  ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI dialplan function\n");
3310  goto end;
3311  }
3312 
3313  if (ast_custom_function_register(&chan_pjsip_parse_uri_from_function)) {
3314  ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI_FROM dialplan function\n");
3315  goto end;
3316  }
3317 
3318  if (ast_custom_function_register(&media_offer_function)) {
3319  ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
3320  goto end;
3321  }
3322 
3323  if (ast_custom_function_register(&dtmf_mode_function)) {
3324  ast_log(LOG_WARNING, "Unable to register PJSIP_DTMF_MODE dialplan function\n");
3325  goto end;
3326  }
3327 
3328  if (ast_custom_function_register(&moh_passthrough_function)) {
3329  ast_log(LOG_WARNING, "Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
3330  goto end;
3331  }
3332 
3333  if (ast_custom_function_register(&session_refresh_function)) {
3334  ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
3335  goto end;
3336  }
3337 
3338  if (ast_register_application_xml(app_pjsip_hangup, pjsip_app_hangup)) {
3339  ast_log(LOG_WARNING, "Unable to register PJSIPHangup dialplan application\n");
3340  goto end;
3341  }
3342  ast_manager_register_xml(app_pjsip_hangup, EVENT_FLAG_SYSTEM | EVENT_FLAG_CALL, pjsip_action_hangup);
3343 
3344 
3345  ast_sip_register_service(&refer_callback_module);
3346 
3347  ast_sip_session_register_supplement(&chan_pjsip_supplement);
3348  ast_sip_session_register_supplement(&chan_pjsip_supplement_response);
3349 
3350  if (!(pjsip_uids_onhold = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK,
3352  uid_hold_sort_fn, NULL))) {
3353  ast_log(LOG_ERROR, "Unable to create held channels container\n");
3354  goto end;
3355  }
3356 
3357  ast_sip_session_register_supplement(&call_pickup_supplement);
3358  ast_sip_session_register_supplement(&pbx_start_supplement);
3359  ast_sip_session_register_supplement(&chan_pjsip_ack_supplement);
3360  ast_sip_session_register_supplement(&chan_pjsip_prack_supplement);
3361 
3363  ast_log(LOG_ERROR, "Unable to register PJSIP Channel CLI\n");
3364  goto end;
3365  }
3366 
3367  /* since endpoints are loaded before the channel driver their device
3368  states get set to 'invalid', so they need to be updated */
3369  if ((endpoints = ast_sip_get_endpoints())) {
3370  ao2_callback(endpoints, OBJ_NODATA, update_devstate, NULL);
3371  ao2_ref(endpoints, -1);
3372  }
3373 
3374  return 0;
3375 
3376 end:
3377  ao2_cleanup(pjsip_uids_onhold);
3378  pjsip_uids_onhold = NULL;
3379  ast_sip_session_unregister_supplement(&chan_pjsip_ack_supplement);
3380  ast_sip_session_unregister_supplement(&chan_pjsip_prack_supplement);
3381  ast_sip_session_unregister_supplement(&pbx_start_supplement);
3382  ast_sip_session_unregister_supplement(&chan_pjsip_supplement_response);
3383  ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
3384  ast_sip_session_unregister_supplement(&call_pickup_supplement);
3385  ast_sip_unregister_service(&refer_callback_module);
3386  ast_custom_function_unregister(&dtmf_mode_function);
3387  ast_custom_function_unregister(&moh_passthrough_function);
3388  ast_custom_function_unregister(&media_offer_function);
3389  ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
3390  ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
3391  ast_custom_function_unregister(&chan_pjsip_parse_uri_from_function);
3392  ast_custom_function_unregister(&session_refresh_function);
3393  ast_unregister_application(app_pjsip_hangup);
3394  ast_manager_unregister(app_pjsip_hangup);
3395 
3398 
3399  return AST_MODULE_LOAD_DECLINE;
3400 }
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
static struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Definition: chan_pjsip.c:155
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1948
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static int uid_hold_hash_fn(const void *obj, const int flags)
Definition: chan_pjsip.c:1067
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int pjsip_action_hangup(struct mansession *s, const struct message *m)
PJSIPHangup Manager Action.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
#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
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
Definition: chan_pjsip.c:143
struct ast_format_cap * capabilities
Definition: channel.h:632
static struct stasis_rest_handlers endpoints
REST handler for /api-docs/endpoints.json.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
Definition: cli_commands.c:462
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
int pjsip_app_hangup(struct ast_channel *chan, const char *data)
PJSIPHangup Dialplan App.
Reject objects with duplicate keys in container.
Definition: astobj2.h:1188
Generic container type.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
Definition: chan_pjsip.c:1085
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
Definition: chan_pjsip.c:486
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.

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

Referenced by load_module().

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 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
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
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.

References OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by load_module().

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 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
Search option field mask.
Definition: astobj2.h:1072
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.

References ao2_ref, AST_CONTROL_TRANSFER, ast_debug, ast_queue_control_data(), AST_TRANSFER_FAILED, and AST_TRANSFER_SUCCESS.

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) {
2046  message = AST_TRANSFER_FAILED;
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) {
2072  ast_queue_control_data(chan, AST_CONTROL_TRANSFER, &message, sizeof(message));
2073  ao2_ref(chan, -1);
2074  }
2075 }
Main Channel structure associated with a channel.
ast_control_transfer
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1948
Definition: astman.c:222
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_debug(level,...)
Log a DEBUG message.
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

Variable Documentation

struct ast_sip_session_supplement call_pickup_supplement
static
Initial value:
= {
.method = "INVITE",
.priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST - 1,
.incoming_request = call_pickup_incoming_request,
}

Definition at line 3070 of file chan_pjsip.c.

struct ast_sip_session_supplement chan_pjsip_ack_supplement
static
Initial value:
= {
.method = "ACK",
.priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL,
.incoming_request = chan_pjsip_incoming_ack,
}

Definition at line 164 of file chan_pjsip.c.

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.

struct ast_custom_function chan_pjsip_parse_uri_from_function
static
Initial value:
= {
.name = "PJSIP_PARSE_URI_FROM",
}
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 3246 of file chan_pjsip.c.

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.

struct ast_sip_session_supplement chan_pjsip_prack_supplement
static
Initial value:
= {
.method = "PRACK",
.priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL,
.incoming_request = chan_pjsip_incoming_prack,
}

Definition at line 172 of file chan_pjsip.c.

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

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

Definition at line 3251 of file chan_pjsip.c.

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

struct ast_sip_session_supplement pbx_start_supplement
static
Initial value:
= {
.method = "INVITE",
.priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST,
.incoming_request = pbx_start_incoming_request,
}

Definition at line 3110 of file chan_pjsip.c.

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.

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

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.