Asterisk - The Open Source Telephony Project
18.5.0
|
#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/bridge.h"
#include "asterisk/framehook.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/causes.h"
Go to the source code of this file.
Data Structures | |
struct | invite_replaces |
Structure used to retrieve channel from another session. More... | |
struct | refer_attended |
Structure for attended transfer task. More... | |
struct | refer_blind |
Structure for blind transfer callback details. More... | |
struct | refer_progress |
REFER Progress structure. More... | |
struct | refer_progress_notification |
REFER Progress notification structure. More... | |
Macros | |
#define | DETERMINE_TRANSFER_CONTEXT(context, session) |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static void | add_header_from_channel_var (struct ast_channel *chan, const char *var_name, const char *header_name, pjsip_tx_data *tdata) |
Use the value of a channel variable as the value of a SIP header. More... | |
struct ast_module * | AST_MODULE_SELF_SYM (void) |
static int | defer_termination_cancel_task (void *data) |
static int | dlg_releaser_task (void *data) |
static int | invite_replaces (void *data) |
Task for invite replaces. More... | |
static int | load_module (void) |
static struct refer_attended * | refer_attended_alloc (struct ast_sip_session *transferer, struct ast_sip_session *transferer_second, struct refer_progress *progress) |
Allocator for attended transfer task. More... | |
static void | refer_attended_destroy (void *obj) |
Destructor for attended transfer task. More... | |
static int | refer_attended_task (void *data) |
Task for attended transfer executed by attended->transferer_second serializer. More... | |
static void | refer_blind_callback (struct ast_channel *chan, struct transfer_channel_data *user_data_wrapper, enum ast_transfer_type transfer_type) |
Blind transfer callback function. More... | |
static int | refer_incoming_attended_request (struct ast_sip_session *session, pjsip_rx_data *rdata, pjsip_sip_uri *target_uri, pjsip_param *replaces_param, struct refer_progress *progress) |
static int | refer_incoming_blind_request (struct ast_sip_session *session, pjsip_rx_data *rdata, pjsip_sip_uri *target, struct refer_progress *progress) |
static int | refer_incoming_invite_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata) |
static int | refer_incoming_refer_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata) |
static int | refer_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata) |
static void | refer_outgoing_request (struct ast_sip_session *session, struct pjsip_tx_data *tdata) |
static int | refer_progress_alloc (struct ast_sip_session *session, pjsip_rx_data *rdata, struct refer_progress **progress) |
Internal helper function which sets up a refer progress structure if needed. More... | |
static void | refer_progress_bridge (void *data, struct stasis_subscription *sub, struct stasis_message *message) |
static void | refer_progress_destroy (void *obj) |
Destructor for REFER progress sutrcture. More... | |
static struct ast_frame * | refer_progress_framehook (struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data) |
Progress monitoring frame hook - examines frames to determine state of transfer. More... | |
static void | refer_progress_framehook_destroy (void *data) |
Destroy callback for monitoring framehook. More... | |
static struct refer_progress_notification * | refer_progress_notification_alloc (struct refer_progress *progress, int response, pjsip_evsub_state state) |
Allocator for REFER Progress notification structure. More... | |
static void | refer_progress_notification_destroy (void *obj) |
Destructor for REFER Progress notification structure. More... | |
static int | refer_progress_notify (void *data) |
Serialized callback for subscription notification. More... | |
static void | refer_progress_on_evsub_state (pjsip_evsub *sub, pjsip_event *event) |
Callback for REFER subscription state changes. More... | |
static int | session_end_if_deferred_task (void *data) |
static int | unload_module (void) |
static int | xfer_response_code2sip (enum ast_transfer_result xfer_code) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Blind and Attended Transfer Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip,res_pjsip_session,res_pjsip_pubsub", } |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static pjsip_evsub_user | refer_progress_evsub_cb |
Callback structure for subscription. More... | |
static pjsip_module | refer_progress_module |
REFER Progress module, used to attach REFER progress structure to subscriptions. More... | |
static struct ast_sip_session_supplement | refer_supplement |
Definition at line 777 of file res_pjsip_refer.c.
Referenced by refer_incoming_attended_request(), and refer_incoming_blind_request().
|
static |
Definition at line 1295 of file res_pjsip_refer.c.
|
static |
Definition at line 1295 of file res_pjsip_refer.c.
|
static |
Use the value of a channel variable as the value of a SIP header.
This looks up a variable name on a channel, then takes that value and adds it to an outgoing SIP request. If the header already exists on the message, then no action is taken.
chan | The channel on which to find the variable. |
var_name | The name of the channel variable to use. |
header_name | The name of the SIP header to add to the outgoing message. |
tdata | The outgoing SIP message on which to add the header |
Definition at line 1223 of file res_pjsip_refer.c.
References ast_sip_add_header(), ast_strlen_zero, NULL, and pbx_builtin_getvar_helper().
Referenced by refer_outgoing_request().
struct ast_module* AST_MODULE_SELF_SYM | ( | void | ) |
Definition at line 1295 of file res_pjsip_refer.c.
|
static |
Definition at line 511 of file res_pjsip_refer.c.
References ao2_ref, ast_sip_session_defer_termination_cancel(), ast_sip_session_end_if_deferred(), and session.
Referenced by refer_attended_task().
|
static |
Definition at line 343 of file res_pjsip_refer.c.
References refer_progress_module.
Referenced by refer_progress_destroy().
|
static |
Task for invite replaces.
Definition at line 954 of file res_pjsip_refer.c.
References ast_bridge_transfer_acquire_bridge(), ast_channel_ref, invite_replaces::bridge, ast_sip_session::channel, invite_replaces::channel, and invite_replaces::session.
|
static |
Definition at line 1262 of file res_pjsip_refer.c.
References AST_MODULE_LOAD_SUCCESS, ast_module_shutdown_ref, ast_sip_get_norefersub(), ast_sip_get_pjsip_endpoint(), ast_sip_register_service(), ast_sip_session_register_supplement, NULL, refer_progress_module, and ast_module_info::self.
Referenced by unload_module().
|
static |
Allocator for attended transfer task.
Definition at line 475 of file res_pjsip_refer.c.
References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_channel_ref, ast_sip_session::channel, NULL, refer_attended::progress, refer_attended_destroy(), refer_attended::transferer, refer_attended::transferer_chan, and refer_attended::transferer_second.
Referenced by refer_incoming_attended_request().
|
static |
Destructor for attended transfer task.
Definition at line 464 of file res_pjsip_refer.c.
References ao2_cleanup, ast_channel_cleanup, refer_attended::progress, refer_attended::transferer, refer_attended::transferer_chan, and refer_attended::transferer_second.
Referenced by refer_attended_alloc().
|
static |
Task for attended transfer executed by attended->transferer_second serializer.
Definition at line 553 of file res_pjsip_refer.c.
References ao2_cleanup, ao2_ref, ast_bridge_transfer_attended(), ast_channel_name(), ast_debug, ast_sip_push_task(), ast_sip_session_end_if_deferred(), ast_sip_session::channel, defer_termination_cancel_task(), NULL, refer_attended::progress, refer_progress_notification_alloc(), refer_progress_notify(), refer_progress::serializer, ast_sip_session::serializer, session_end_if_deferred_task(), refer_attended::transferer, refer_attended::transferer_chan, refer_attended::transferer_second, and xfer_response_code2sip().
Referenced by refer_incoming_attended_request().
|
static |
Blind transfer callback function.
Definition at line 625 of file res_pjsip_refer.c.
References ao2_cleanup, ao2_ref, ast_alloca, ast_bridge_topic_all(), ast_channel_entered_bridge_type(), ast_channel_lock, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_copy_pj_str(), ast_framehook_attach(), ast_framehook_detach(), AST_FRAMEHOOK_INTERFACE_VERSION, ast_log, ast_sip_push_task(), ast_strdup, refer_blind::attended, refer_progress::bridge_sub, refer_blind::context, transfer_channel_data::data, refer_progress::framehook, len(), LOG_WARNING, NULL, pbx_builtin_setvar_helper(), refer_blind::progress, refer_blind::rdata, refer_progress::refer_blind_progress, refer_progress_bridge(), refer_progress_framehook(), refer_progress_framehook_destroy(), refer_progress_notification_alloc(), refer_progress_notify(), refer_blind::refer_to, refer_blind::replaces, S_OR, refer_progress::serializer, stasis_subscribe_pool, stasis_subscription_accept_message_type(), stasis_subscription_change_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), refer_progress::transfer_data, refer_progress::transferee, and ast_framehook_interface::version.
Referenced by refer_incoming_attended_request(), and refer_incoming_blind_request().
|
static |
Definition at line 789 of file res_pjsip_refer.c.
References ao2_cleanup, ast_bridge_transfer_blind(), ast_channel_name(), ast_debug, ast_exists_extension(), ast_log, ast_sip_dialog_get_session(), ast_sip_push_task(), ast_sip_session_defer_termination(), ast_sip_session_defer_termination_cancel(), ast_sip_session_end_if_deferred(), ast_sorcery_object_get_id(), refer_blind::attended, ast_sip_session::channel, context, refer_blind::context, DETERMINE_TRANSFER_CONTEXT, refer_progress::dlg, ast_sip_session::endpoint, LOG_ERROR, NULL, refer_blind::progress, RAII_VAR, refer_progress::rdata, refer_blind::rdata, refer_attended_alloc(), refer_attended_task(), refer_blind_callback(), refer_blind::refer_to, refer_blind::replaces, and xfer_response_code2sip().
Referenced by refer_incoming_refer_request().
|
static |
Definition at line 886 of file res_pjsip_refer.c.
References ast_bridge_transfer_blind(), ast_channel_name(), ast_copy_pj_str(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log, AST_MAX_EXTENSION, ast_sip_session_defer_termination(), ast_sip_session_defer_termination_cancel(), ast_sip_session_end_if_deferred(), AST_SIP_USER_OPTIONS_TRUNCATE_CHECK, ast_sorcery_object_get_id(), ast_strlen_zero, refer_blind::attended, ast_sip_session::channel, context, refer_blind::context, DETERMINE_TRANSFER_CONTEXT, ast_sip_session::endpoint, exten, LOG_ERROR, NULL, refer_blind::progress, refer_progress::rdata, refer_blind::rdata, refer_blind_callback(), refer_blind::refer_to, and xfer_response_code2sip().
Referenced by refer_incoming_refer_request().
|
static |
Definition at line 969 of file res_pjsip_refer.c.
References ao2_cleanup, ast_assert, ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, AST_CAUSE_FAILURE, ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_move(), ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_debug, ast_hangup(), ast_queue_hangup(), ast_raw_answer(), ast_setstate(), ast_sip_dialog_get_session(), ast_sip_push_task_wait_serializer(), ast_sip_session_send_response(), ast_sorcery_object_get_id(), AST_STATE_RING, invite_replaces::bridge, ast_sip_session::channel, invite_replaces::channel, ast_sip_session::defer_terminate, ast_sip_session::endpoint, ast_sip_session::inv_session, NULL, RAII_VAR, and invite_replaces::session.
Referenced by refer_incoming_request().
|
static |
Definition at line 1088 of file res_pjsip_refer.c.
References ast_sip_endpoint::allowtransfer, ao2_cleanup, ast_alloca, ast_channel_name(), ast_copy_pj_str(), ast_debug, ast_log, ast_sip_push_task(), ast_sorcery_object_get_id(), ast_sip_session::channel, ast_sip_session::endpoint, ast_sip_session::inv_session, LOG_WARNING, NULL, RAII_VAR, refer_incoming_attended_request(), refer_incoming_blind_request(), refer_progress_alloc(), refer_progress_notification_alloc(), and refer_progress_notify().
Referenced by refer_incoming_request().
|
static |
Definition at line 1198 of file res_pjsip_refer.c.
References refer_incoming_invite_request(), and refer_incoming_refer_request().
|
static |
Definition at line 1242 of file res_pjsip_refer.c.
References add_header_from_channel_var(), ast_channel_lock, ast_channel_unlock, ast_sip_session::channel, and ast_sip_session::inv_session.
|
static |
Internal helper function which sets up a refer progress structure if needed.
Definition at line 382 of file res_pjsip_refer.c.
References ao2_alloc, ao2_cleanup, ao2_ref, ast_channel_name(), ast_debug, ast_sip_create_serializer(), ast_sorcery_object_get_id(), ast_taskprocessor_build_name(), AST_TASKPROCESSOR_MAX_NAME, ast_sip_session::channel, ast_sip_session::endpoint, error(), ast_sip_session::inv_session, NULL, ast_sip_endpoint::refer_blind_progress, refer_progress_destroy(), refer_progress_evsub_cb, and refer_progress_module.
Referenced by refer_incoming_refer_request().
|
static |
Definition at line 181 of file res_pjsip_refer.c.
References ao2_cleanup, ao2_ref, ast_channel_entered_bridge_type(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_debug, ast_framehook_detach(), ast_sip_push_task(), ast_channel_snapshot::base, refer_progress::bridge_sub, ast_bridge_blob::channel, transfer_channel_data::completed, refer_progress::framehook, refer_progress_notification_alloc(), refer_progress_notify(), refer_progress::serializer, stasis_message_data(), stasis_message_type(), stasis_subscription_final_message(), stasis_unsubscribe(), refer_progress::transfer_data, refer_progress::transferee, and ast_channel_snapshot_base::uniqueid.
Referenced by refer_blind_callback().
|
static |
Destructor for REFER progress sutrcture.
Definition at line 349 of file res_pjsip_refer.c.
References ao2_cleanup, ast_free, ast_sip_push_task(), ast_sip_thread_is_servant(), ast_taskprocessor_unreference(), refer_progress::bridge_sub, refer_progress::dlg, dlg_releaser_task(), NULL, refer_progress_module, refer_progress::serializer, stasis_unsubscribe(), refer_progress::transfer_data, and refer_progress::transferee.
Referenced by refer_progress_alloc().
|
static |
Progress monitoring frame hook - examines frames to determine state of transfer.
Definition at line 236 of file res_pjsip_refer.c.
References ao2_cleanup, ast_channel_name(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RING, AST_CONTROL_RINGING, ast_debug, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_framehook_detach(), AST_FRAMEHOOK_EVENT_WRITE, ast_sip_push_task(), transfer_channel_data::completed, refer_progress::framehook, ast_frame::frametype, ast_frame_subclass::integer, NULL, refer_progress_notification_alloc(), refer_progress_notify(), refer_progress::serializer, refer_progress_notification::state, refer_progress::subclass, ast_frame::subclass, and refer_progress::transfer_data.
Referenced by refer_blind_callback().
|
static |
Destroy callback for monitoring framehook.
Definition at line 297 of file res_pjsip_refer.c.
References ao2_cleanup, ast_sip_push_task(), refer_progress::bridge_sub, refer_progress_notification_alloc(), refer_progress_notify(), refer_progress::serializer, and stasis_unsubscribe().
Referenced by refer_blind_callback().
|
static |
Allocator for REFER Progress notification structure.
Definition at line 94 of file res_pjsip_refer.c.
References ao2_alloc, ao2_ref, NULL, refer_progress_notification::progress, refer_progress_notification_destroy(), refer_progress_notification::response, refer_progress_notification::state, and state.
Referenced by refer_attended_task(), refer_blind_callback(), refer_incoming_refer_request(), refer_progress_bridge(), refer_progress_framehook(), and refer_progress_framehook_destroy().
|
static |
Destructor for REFER Progress notification structure.
Definition at line 86 of file res_pjsip_refer.c.
References ao2_cleanup, and refer_progress_notification::progress.
Referenced by refer_progress_notification_alloc().
|
static |
Serialized callback for subscription notification.
Locking and serialization:
Although refer_progress_notify() always runs in the progress serializer, the pjproject evsub module itself can cause the subscription to be destroyed which then triggers refer_progress_on_evsub_state() to clean it up. In this case, it's possible that refer_progress_notify() could get the subscription pulled out from under it while it's trying to use it.
At one point we tried to have refer_progress_on_evsub_state() push the cleanup to the serializer and wait for its return before returning to pjproject but since pjproject calls its state callbacks with the dialog locked, this required us to unlock the dialog while waiting for the serialized cleanup, then lock it again before returning to pjproject. There were also still some cases where other callers of refer_progress_notify() weren't using the serializer and crashes were resulting.
Although all callers of refer_progress_notify() now use the progress serializer, we decided to simplify the locking so we didn't have to unlock and relock the dialog in refer_progress_on_evsub_state().
Now, refer_progress_notify() holds the dialog lock for all its work rather than just when calling pjsip_evsub_set_mod_data() to clear the module data. Since pjproject also holds the dialog lock while calling refer_progress_on_evsub_state(), there should be no more chances for the subscription to be cleaned up while still being used to send NOTIFYs.
Definition at line 140 of file res_pjsip_refer.c.
References ao2_cleanup, ast_debug, NULL, RAII_VAR, and refer_progress::sub.
Referenced by refer_attended_task(), refer_blind_callback(), refer_incoming_refer_request(), refer_progress_bridge(), refer_progress_framehook(), and refer_progress_framehook_destroy().
|
static |
Callback for REFER subscription state changes.
The documentation attached to refer_progress_notify has more information about the locking issues with cleaning up the subscription.
Definition at line 323 of file res_pjsip_refer.c.
References ao2_cleanup, NULL, refer_progress_module, and refer_progress::sub.
|
static |
Definition at line 502 of file res_pjsip_refer.c.
References ao2_ref, ast_sip_session_end_if_deferred(), and session.
Referenced by refer_attended_task().
|
static |
Definition at line 1281 of file res_pjsip_refer.c.
References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_APP_DEPEND, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_sip_session_unregister_supplement(), ast_sip_unregister_service(), ASTERISK_GPL_KEY, load_module(), and refer_progress_module.
|
static |
Definition at line 530 of file res_pjsip_refer.c.
References AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, and AST_BRIDGE_TRANSFER_SUCCESS.
Referenced by refer_attended_task(), refer_incoming_attended_request(), and refer_incoming_blind_request().
|
static |
Definition at line 1295 of file res_pjsip_refer.c.
|
static |
Definition at line 1295 of file res_pjsip_refer.c.
|
static |
Callback structure for subscription.
Definition at line 339 of file res_pjsip_refer.c.
Referenced by refer_progress_alloc().
|
static |
REFER Progress module, used to attach REFER progress structure to subscriptions.
Definition at line 80 of file res_pjsip_refer.c.
Referenced by dlg_releaser_task(), load_module(), refer_progress_alloc(), refer_progress_destroy(), refer_progress_on_evsub_state(), and unload_module().
|
static |
Definition at line 1256 of file res_pjsip_refer.c.