Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Enumerations | Functions | Variables
bridge_basic.c File Reference

Basic bridge class. It is a subclass of struct ast_bridge. More...

#include "asterisk.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_internal.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/bridge_after.h"
#include "asterisk/astobj2.h"
#include "asterisk/features_config.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/dial.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/features.h"
#include "asterisk/format_cache.h"
#include "asterisk/test.h"
Include dependency graph for bridge_basic.c:

Go to the source code of this file.

Data Structures

struct  attended_transfer_properties
 Collection of data related to an attended transfer attempt. More...
 
struct  attended_transfer_state_properties
 Properties of an attended transfer state. More...
 
struct  bridge_basic_personality
 structure that organizes different personalities for basic bridges. More...
 
struct  dynamic_dtmf_hook_data
 
struct  dynamic_dtmf_hook_run
 
struct  personality_details
 Details for specific basic bridge personalities. More...
 
struct  stimulus_list
 

Macros

#define NORMAL_FLAGS
 
#define TRANSFER_FLAGS   AST_BRIDGE_FLAG_SMART
 

Enumerations

enum  attended_transfer_state {
  TRANSFER_CALLING_TARGET , TRANSFER_HESITANT , TRANSFER_REBRIDGE , TRANSFER_RESUME ,
  TRANSFER_THREEWAY , TRANSFER_CONSULTING , TRANSFER_DOUBLECHECKING , TRANSFER_COMPLETE ,
  TRANSFER_BLOND , TRANSFER_BLOND_NONFINAL , TRANSFER_RECALLING , TRANSFER_WAIT_TO_RETRANSFER ,
  TRANSFER_RETRANSFER , TRANSFER_WAIT_TO_RECALL , TRANSFER_FAIL
}
 
enum  attended_transfer_state_flags {
  TRANSFER_STATE_FLAG_TIMER_RESET = (1 << 0) , TRANSFER_STATE_FLAG_TIMER_LOOP_DELAY = (1 << 1) , TRANSFER_STATE_FLAG_ATXFER_NO_ANSWER = (1 << 2) , TRANSFER_STATE_FLAG_TIMED ,
  TRANSFER_STATE_FLAG_TERMINAL = (1 << 3)
}
 Flags that indicate properties of attended transfer states. More...
 
enum  attended_transfer_stimulus {
  STIMULUS_NONE , STIMULUS_TRANSFEREE_HANGUP , STIMULUS_TRANSFERER_HANGUP , STIMULUS_TRANSFER_TARGET_HANGUP ,
  STIMULUS_TRANSFER_TARGET_ANSWER , STIMULUS_RECALL_TARGET_HANGUP , STIMULUS_RECALL_TARGET_ANSWER , STIMULUS_TIMEOUT ,
  STIMULUS_DTMF_ATXFER_ABORT , STIMULUS_DTMF_ATXFER_COMPLETE , STIMULUS_DTMF_ATXFER_THREEWAY , STIMULUS_DTMF_ATXFER_SWAP
}
 Stimuli that can cause transfer state changes. More...
 
enum  attended_transfer_superstate { SUPERSTATE_TRANSFER , SUPERSTATE_RECALL }
 Attended transfer superstates. More...
 
enum  bridge_basic_personality_type { BRIDGE_BASIC_PERSONALITY_NORMAL , BRIDGE_BASIC_PERSONALITY_ATXFER , BRIDGE_BASIC_PERSONALITY_END }
 

Functions

static int add_normal_hooks (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 
static int add_transferer_role (struct ast_channel *chan, struct ast_bridge_features_attended_transfer *attended_transfer)
 
struct ast_bridgeast_bridge_basic_new (void)
 Create a new basic class bridge. More...
 
void ast_bridge_basic_set_flags (struct ast_bridge *bridge, unsigned int flags)
 Set feature flags on a basic bridge. More...
 
int ast_bridge_features_ds_append (struct ast_channel *chan, struct ast_flags *flags)
 Append basic bridge DTMF feature flags on the channel. More...
 
struct ast_flagsast_bridge_features_ds_get (struct ast_channel *chan)
 Get DTMF feature flags from the channel. More...
 
int ast_bridge_features_ds_get_string (struct ast_channel *chan, char *buffer, size_t buf_size)
 writes a channel's DTMF features to a buffer string More...
 
int ast_bridge_features_ds_set (struct ast_channel *chan, struct ast_flags *flags)
 Set basic bridge DTMF feature flags datastore on the channel. More...
 
int ast_bridge_features_ds_set_string (struct ast_channel *chan, const char *features)
 Sets the features a channel will use upon being bridged. More...
 
void ast_bridging_init_basic (void)
 
static int attach_framehook (struct attended_transfer_properties *props, struct ast_channel *channel)
 
static void * attended_transfer_monitor_thread (void *data)
 The main loop for the attended transfer monitor thread. More...
 
static struct attended_transfer_propertiesattended_transfer_properties_alloc (struct ast_channel *transferer, const char *context)
 Allocate and initialize attended transfer properties. More...
 
static void attended_transfer_properties_destructor (void *obj)
 
static void attended_transfer_properties_shutdown (struct attended_transfer_properties *props)
 Initiate shutdown of attended transfer properties. More...
 
static int atxfer_abort (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 DTMF hook when transferer presses abort sequence. More...
 
static int atxfer_complete (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 DTMF hook when transferer presses complete sequence. More...
 
static int atxfer_swap (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 DTMF hook when transferer presses swap sequence. More...
 
static int atxfer_threeway (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 DTMF hook when transferer presses threeway sequence. More...
 
static int atxfer_transferer_hangup (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 Hangup hook for transferer channel. More...
 
static int basic_hangup_hook (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 
static void blind_transfer_cb (struct ast_channel *new_channel, struct transfer_channel_data *user_data_wrapper, enum ast_transfer_type transfer_type)
 
static int blond_enter (struct attended_transfer_properties *props)
 
static int blond_nonfinal_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state blond_nonfinal_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void bridge_basic_change_personality (struct ast_bridge *bridge, enum bridge_basic_personality_type type, void *user_data)
 Change basic bridge personality. More...
 
static void bridge_basic_destroy (struct ast_bridge *self)
 
static struct ast_bridgebridge_basic_personality_alloc (struct ast_bridge *bridge)
 
static void bridge_basic_pull (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
 
static int bridge_basic_push (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 
static int bridge_basic_setup_features (struct ast_bridge_channel *bridge_channel)
 
static int bridge_features_ds_set_full (struct ast_channel *chan, struct ast_flags *flags, int replace)
 
static void bridge_hold (struct ast_bridge *bridge)
 Helper method to send a hold frame to all channels in a bridge. More...
 
static void bridge_merge (struct ast_bridge *dest, struct ast_bridge *src, struct ast_channel **kick_channels, unsigned int num_channels)
 Wrapper for bridge_do_merge. More...
 
static void bridge_move (struct ast_bridge *dest, struct ast_bridge *src, struct ast_channel *channel, struct ast_channel *swap)
 Wrapper for bridge_do_move. More...
 
static void bridge_personality_atxfer_pull (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
 
static int bridge_personality_atxfer_push (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 
static int bridge_personality_normal_push (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 
static void bridge_ringing (struct ast_bridge *bridge)
 Helper method to send a ringing indication to all channels in a bridge. More...
 
static void bridge_unhold (struct ast_bridge *bridge)
 Helper method to send an unhold frame to all channels in a bridge. More...
 
static int build_dtmf_features (struct ast_flags *flags, const char *features)
 
static int builtin_feature_get_exten (struct ast_channel *chan, const char *feature_name, char *buf, size_t len)
 
static int builtin_features_helper (struct ast_bridge_features *features, struct ast_channel *chan, struct ast_flags *flags, unsigned int feature_flag, const char *feature_name, enum ast_bridge_builtin_feature feature_bridge)
 
static int calling_target_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state calling_target_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void clear_stimulus_queue (struct attended_transfer_properties *props)
 Free backlog of stimuli in the queue. More...
 
static void common_recall_channel_setup (struct ast_channel *recall, struct ast_channel *transferer)
 
static int complete_enter (struct attended_transfer_properties *props)
 
static int consulting_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state consulting_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void copy_caller_data (struct ast_channel *dest, struct ast_channel *caller)
 
static struct ast_channeldial_transfer (struct ast_channel *caller, const char *destination)
 Helper function that creates an outgoing channel and returns it immediately. More...
 
static int double_checking_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state double_checking_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static int dtmf_features_flags_to_string (struct ast_flags *feature_flags, char *buffer, size_t buffer_size)
 
static int dynamic_dtmf_hook_add (struct ast_bridge_features *features, unsigned int flags, const char *dtmf, const char *feature_name, const char *app_name, const char *app_args, const char *moh_class)
 
static void dynamic_dtmf_hook_callback (struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
 
static int dynamic_dtmf_hook_trip (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 
static int fail_enter (struct attended_transfer_properties *props)
 
static int feature_attended_transfer (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 Internal built in feature for attended transfers. More...
 
static int feature_blind_transfer (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 Internal built in feature for blind transfers. More...
 
static const char * get_transfer_context (struct ast_channel *transferer, const char *context)
 
static const char * get_transfer_exten (struct ast_channel *transferer, const char *exten)
 
static void get_transfer_parties (struct ast_channel *transferer, struct ast_bridge *transferee_bridge, struct ast_bridge *target_bridge, struct ast_channel **transferee, struct ast_channel **transfer_target)
 determine transferee and transfer target for an attended transfer More...
 
static void get_transfer_parties_transferer_bridge (struct ast_bridge *transferer_bridge, struct ast_bridge *other_bridge, struct ast_channel *transferer, struct ast_channel **transferer_peer, struct ast_channel **other_party)
 Get the transferee and transfer target when the transferer is in a bridge with one of the desired parties. More...
 
static void get_transfer_party_non_transferer_bridge (struct ast_bridge *bridge, struct ast_channel **party)
 Get a desired transfer party for a bridge the transferer is not in. More...
 
static int grab_transfer (struct ast_channel *chan, char *exten, size_t exten_len, const char *context)
 Helper function that presents dialtone and grabs extension. More...
 
static int hesitant_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state hesitant_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void hold (struct ast_channel *chan)
 Helper method to place a channel in a bridge on hold. More...
 
static void init_details (struct personality_details *details, enum bridge_basic_personality_type type)
 
static void on_personality_change_normal (struct ast_bridge *bridge)
 
static void personality_destructor (void *obj)
 
static void play_failsound (struct ast_channel *chan)
 Helper method to play a fail sound on a channel in a bridge. More...
 
static void play_sound (struct ast_channel *chan, const char *sound)
 Helper method to play a sound on a channel in a bridge. More...
 
static void publish_transfer_fail (struct attended_transfer_properties *props)
 Send a stasis publication for a failed attended transfer. More...
 
static void publish_transfer_success (struct attended_transfer_properties *props, struct ast_channel *transferee_channel, struct ast_channel *target_channel)
 Send a stasis publication for a successful attended transfer. More...
 
static void publish_transfer_threeway (struct attended_transfer_properties *props, struct ast_channel *transferee_channel, struct ast_channel *target_channel)
 Send a stasis publication for an attended transfer that ends in a threeway call. More...
 
static int rebridge_enter (struct attended_transfer_properties *props)
 
static void recall_callback (struct ast_dial *dial)
 Dial callback when attempting to recall the original transferer channel. More...
 
static void recall_pull (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct attended_transfer_properties *props)
 
static int recalling_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state recalling_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void remove_attended_transfer_stimulus (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void remove_hooks_on_personality_change (struct ast_bridge *bridge)
 Remove appropriate hooks when basic bridge personality changes. More...
 
static int resume_enter (struct attended_transfer_properties *props)
 
static int retransfer_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state retransfer_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void ringing (struct ast_channel *chan)
 Helper method to send a ringing indication to a channel in a bridge. More...
 
static int set_feature_flag_from_char (struct ast_flags *feature_flags, char feature)
 
static int setup_bridge_features_builtin (struct ast_bridge_features *features, struct ast_channel *chan)
 
static int setup_bridge_features_dynamic (struct ast_bridge_features *features, struct ast_channel *chan)
 
static int setup_dynamic_feature (void *obj, void *arg, void *data, int flags)
 
static void stimulate_attended_transfer (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static void stream_failsound (struct ast_channel *chan)
 Helper method to stream a fail sound on a channel. More...
 
static int threeway_enter (struct attended_transfer_properties *props)
 
static void transfer_pull (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct attended_transfer_properties *props)
 
static struct ast_frametransfer_target_framehook_cb (struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
 Frame hook for transfer target channel. More...
 
static int transfer_target_framehook_consume (void *data, enum ast_frame_type type)
 Callback function which informs upstream if we are consuming a frame of a specific type. More...
 
static void transfer_target_framehook_destroy_cb (void *data)
 
static void unhold (struct ast_channel *chan)
 Helper method to take a channel in a bridge off hold. More...
 
static enum attended_transfer_stimulus wait_for_stimulus (struct attended_transfer_properties *props)
 
static int wait_to_recall_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state wait_to_recall_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 
static int wait_to_retransfer_enter (struct attended_transfer_properties *props)
 
static enum attended_transfer_state wait_to_retransfer_exit (struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
 

Variables

struct ast_bridge_methods ast_bridge_basic_v_table
 Bridge basic class virtual method table. More...
 
static const struct ast_datastore_info dtmf_features_info
 
struct ast_bridge_methods personality_atxfer_v_table
 
struct ast_bridge_methods personality_normal_v_table
 
static const struct attended_transfer_state_properties state_properties []
 
const char * stimulus_strs []
 String representations of the various stimuli. More...
 

Detailed Description

Basic bridge class. It is a subclass of struct ast_bridge.

Author
Richard Mudgett rmudg.nosp@m.ett@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

See Also:

Definition in file bridge_basic.c.

Macro Definition Documentation

◆ NORMAL_FLAGS

#define NORMAL_FLAGS
Value:

Definition at line 51 of file bridge_basic.c.

◆ TRANSFER_FLAGS

#define TRANSFER_FLAGS   AST_BRIDGE_FLAG_SMART

Definition at line 54 of file bridge_basic.c.

Enumeration Type Documentation

◆ attended_transfer_state

The states in the attended transfer state machine.

Enumerator
TRANSFER_CALLING_TARGET 

Calling Target state.

This state describes the initial state of a transfer. The transferer waits in the transfer target's bridge for the transfer target to answer.

Superstate: Transfer

Preconditions: 1) Transfer target is RINGING 2) Transferer is in transferee bridge 3) Transferee is on hold

Transitions to TRANSFER_CALLING_TARGET: 1) This is the initial state for an attended transfer. 2) TRANSFER_HESITANT: Transferer presses DTMF swap sequence

State operation: The transferer is moved from the transferee bridge into the transfer target bridge.

Transitions from TRANSFER_CALLING_TARGET: 1) TRANSFER_FAIL: Transferee hangs up. 2) TRANSFER_BLOND: Transferer hangs up or presses DTMF swap sequence and configured atxferdropcall setting is yes. 3) TRANSFER_BLOND_NONFINAL: Transferer hangs up or presses DTMF swap sequence and configured atxferdropcall setting is no. 4) TRANSFER_CONSULTING: Transfer target answers the call. 5) TRANSFER_REBRIDGE: Transfer target hangs up, call to transfer target times out, or transferer presses DTMF abort sequence. 6) TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence. 7) TRANSFER_HESITANT: Transferer presses DTMF swap sequence.

TRANSFER_HESITANT 

Hesitant state.

This state only arises if when waiting for the transfer target to answer, the transferer presses the DTMF swap sequence. This will cause the transferer to be rebridged with the transferee temporarily.

Superstate: Transfer

Preconditions: 1) Transfer target is in ringing state 2) Transferer is in transfer target bridge 3) Transferee is on hold

Transitions to TRANSFER_HESITANT: 1) TRANSFER_CALLING_TARGET: Transferer presses DTMF swap sequence.

State operation: The transferer is moved from the transfer target bridge into the transferee bridge, and the transferee is taken off hold.

Transitions from TRANSFER_HESITANT: 1) TRANSFER_FAIL: Transferee hangs up 2) TRANSFER_BLOND: Transferer hangs up or presses DTMF swap sequence and configured atxferdropcall setting is yes. 3) TRANSFER_BLOND_NONFINAL: Transferer hangs up or presses DTMF swap sequence and configured atxferdropcall setting is no. 4) TRANSFER_DOUBLECHECKING: Transfer target answers the call 5) TRANSFER_RESUME: Transfer target hangs up, call to transfer target times out, or transferer presses DTMF abort sequence. 6) TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence. 7) TRANSFER_CALLING_TARGET: Transferer presses DTMF swap sequence.

TRANSFER_REBRIDGE 

Rebridge state.

This is a terminal state that indicates that the transferer needs to move back to the transferee's bridge. This is a failed attended transfer result.

Superstate: Transfer

Preconditions: 1) Transferer is in transfer target bridge 2) Transferee is on hold

Transitions to TRANSFER_REBRIDGE: 1) TRANSFER_CALLING_TARGET: Transfer target hangs up, call to transfer target times out, or transferer presses DTMF abort sequence. 2) TRANSFER_STATE_CONSULTING: Transfer target hangs up, or transferer presses DTMF abort sequence.

State operation: The transferer channel is moved from the transfer target bridge to the transferee bridge. The transferee is taken off hold. A stasis transfer message is published indicating a failed attended transfer.

Transitions from TRANSFER_REBRIDGE: None

TRANSFER_RESUME 

Resume state.

This is a terminal state that indicates that the party bridged with the transferee is the final party to be bridged with that transferee. This state may come about due to a successful recall or due to a failed transfer.

Superstate: Transfer or Recall

Preconditions: In Transfer Superstate: 1) Transferer is in transferee bridge 2) Transferee is not on hold In Recall Superstate: 1) The recall target is in the transferee bridge 2) Transferee is not on hold

Transitions to TRANSFER_RESUME: TRANSFER_HESITANT: Transfer target hangs up, call to transfer target times out, or transferer presses DTMF abort sequence. TRANSFER_DOUBLECHECKING: Transfer target hangs up or transferer presses DTMF abort sequence. TRANSFER_BLOND_NONFINAL: Recall target answers TRANSFER_RECALLING: Recall target answers TRANSFER_RETRANSFER: Recall target answers

State operations: None

Transitions from TRANSFER_RESUME: None

TRANSFER_THREEWAY 

Threeway state.

This state results when the transferer wishes to have all parties involved in a transfer to be in the same bridge together.

Superstate: Transfer

Preconditions: 1) Transfer target state is either RINGING or UP 2) Transferer is in either bridge 3) Transferee is not on hold

Transitions to TRANSFER_THREEWAY: 1) TRANSFER_CALLING_TARGET: Transferer presses DTMF threeway sequence. 2) TRANSFER_HESITANT: Transferer presses DTMF threeway sequence. 3) TRANSFER_CONSULTING: Transferer presses DTMF threeway sequence. 4) TRANSFER_DOUBLECHECKING: Transferer presses DTMF threeway sequence.

State operation: The transfer target bridge is merged into the transferee bridge.

Transitions from TRANSFER_THREEWAY: None.

TRANSFER_CONSULTING 

Consulting state.

This state describes the case where the transferer and transfer target are able to converse in the transfer target's bridge prior to completing the transfer.

Superstate: Transfer

Preconditions: 1) Transfer target is UP 2) Transferer is in target bridge 3) Transferee is on hold

Transitions to TRANSFER_CONSULTING: 1) TRANSFER_CALLING_TARGET: Transfer target answers. 2) TRANSFER_DOUBLECHECKING: Transferer presses DTMF swap sequence.

State operations: None.

Transitions from TRANSFER_CONSULTING: TRANSFER_COMPLETE: Transferer hangs up or transferer presses DTMF complete sequence. TRANSFER_REBRIDGE: Transfer target hangs up or transferer presses DTMF abort sequence. TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence. TRANSFER_DOUBLECHECKING: Transferer presses DTMF swap sequence.

TRANSFER_DOUBLECHECKING 

Double-checking state.

This state describes the case where the transferer and transferee are able to converse in the transferee's bridge prior to completing the transfer. The difference between this and TRANSFER_HESITANT is that the transfer target is UP in this case.

Superstate: Transfer

Preconditions: 1) Transfer target is UP and on hold 2) Transferer is in transferee bridge 3) Transferee is off hold

Transitions to TRANSFER_DOUBLECHECKING: 1) TRANSFER_HESITANT: Transfer target answers. 2) TRANSFER_CONSULTING: Transferer presses DTMF swap sequence.

State operations: None.

Transitions from TRANSFER_DOUBLECHECKING: 1) TRANSFER_FAIL: Transferee hangs up. 2) TRANSFER_COMPLETE: Transferer hangs up or presses DTMF complete sequence. 3) TRANSFER_RESUME: Transfer target hangs up or transferer presses DTMF abort sequence. 4) TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence. 5) TRANSFER_CONSULTING: Transferer presses the DTMF swap sequence.

TRANSFER_COMPLETE 

Complete state.

This is a terminal state where a transferer has successfully completed an attended transfer. This state's goal is to get the transfer target and transferee into the same bridge and the transferer off the call.

Superstate: Transfer

Preconditions: 1) Transfer target is UP and off hold. 2) Transferer is in either bridge. 3) Transferee is off hold.

Transitions to TRANSFER_COMPLETE: 1) TRANSFER_CONSULTING: transferer hangs up or presses the DTMF complete sequence. 2) TRANSFER_DOUBLECHECKING: transferer hangs up or presses the DTMF complete sequence.

State operation: The transfer target bridge is merged into the transferee bridge. The transferer channel is kicked out of the bridges as part of the merge.

State operations: 1) Merge the transfer target bridge into the transferee bridge, excluding the transferer channel from the merge. 2) Publish a stasis transfer message.

Exit operations: This is a terminal state, so there are no exit operations.

TRANSFER_BLOND 

Blond state.

This is a terminal state where a transferer has completed an attended transfer prior to the transfer target answering. This state is only entered if atxferdropcall is set to 'yes'. This is considered to be a successful attended transfer.

Superstate: Transfer

Preconditions: 1) Transfer target is RINGING. 2) Transferer is in either bridge. 3) Transferee is off hold.

Transitions to TRANSFER_BLOND: 1) TRANSFER_CALLING_TARGET: Transferer hangs up or presses the DTMF complete sequence. atxferdropcall is set to 'yes'. 2) TRANSFER_HESITANT: Transferer hangs up or presses the DTMF complete sequence. atxferdropcall is set to 'yes'.

State operations: The transfer target bridge is merged into the transferee bridge. The transferer channel is kicked out of the bridges as part of the merge. A stasis transfer publication is sent indicating a successful transfer.

Transitions from TRANSFER_BLOND: None

TRANSFER_BLOND_NONFINAL 

Blond non-final state.

This state is very similar to the TRANSFER_BLOND state, except that this state is entered when atxferdropcall is set to 'no'. This is the initial state of the Recall superstate, so state operations mainly involve moving to the Recall superstate. This means that the transfer target, that is currently ringing is now known as the recall target.

Superstate: Recall

Preconditions: 1) Recall target is RINGING. 2) Transferee is off hold.

Transitions to TRANSFER_BLOND_NONFINAL: 1) TRANSFER_CALLING_TARGET: Transferer hangs up or presses the DTMF complete sequence. atxferdropcall is set to 'no'. 2) TRANSFER_HESITANT: Transferer hangs up or presses the DTMF complete sequence. atxferdropcall is set to 'no'.

State operation: The superstate of the attended transfer is changed from Transfer to Recall. The transfer target bridge is merged into the transferee bridge. The transferer channel is kicked out of the bridges as part of the merge.

Transitions from TRANSFER_BLOND_NONFINAL: 1) TRANSFER_FAIL: Transferee hangs up 2) TRANSFER_RESUME: Recall target answers 3) TRANSFER_RECALLING: Recall target hangs up or time expires.

TRANSFER_RECALLING 

Recalling state.

This state is entered if the recall target from the TRANSFER_BLOND_NONFINAL or TRANSFER_RETRANSFER states hangs up or does not answer. The goal of this state is to call back the original transferer in an attempt to recover the original call.

Superstate: Recall

Preconditions: 1) Recall target is down. 2) Transferee is off hold.

Transitions to TRANSFER_RECALLING: 1) TRANSFER_BLOND_NONFINAL: Recall target hangs up or time expires. 2) TRANSFER_RETRANSFER: Recall target hangs up or time expires. atxferloopdelay is non-zero. 3) TRANSFER_WAIT_TO_RECALL: Time expires.

State operation: The original transferer becomes the recall target and is called using the Dialing API. Ringing is indicated to the transferee.

Transitions from TRANSFER_RECALLING: 1) TRANSFER_FAIL: a) Transferee hangs up. b) Recall target hangs up or time expires, and number of recall attempts exceeds atxfercallbackretries 2) TRANSFER_WAIT_TO_RETRANSFER: Recall target hangs up or time expires. atxferloopdelay is non-zero. 3) TRANSFER_RETRANSFER: Recall target hangs up or time expires. atxferloopdelay is zero. 4) TRANSFER_RESUME: Recall target answers.

TRANSFER_WAIT_TO_RETRANSFER 

Wait to Retransfer state.

This state is used simply to give a bit of breathing room between attempting to call back the original transferer and attempting to call back the original transfer target. The transferee hears music on hold during this state as an auditory clue that no one is currently being dialed.

Superstate: Recall

Preconditions: 1) Recall target is down. 2) Transferee is off hold.

Transitions to TRANSFER_WAIT_TO_RETRANSFER: 1) TRANSFER_RECALLING: Recall target hangs up or time expires. atxferloopdelay is non-zero.

State operation: The transferee is placed on hold.

Transitions from TRANSFER_WAIT_TO_RETRANSFER: 1) TRANSFER_FAIL: Transferee hangs up. 2) TRANSFER_RETRANSFER: Time expires.

TRANSFER_RETRANSFER 

Retransfer state.

This state is used in order to attempt to call back the original transfer target channel from the transfer. The transferee hears ringing during this state as an auditory cue that a party is being dialed.

Superstate: Recall

Preconditions: 1) Recall target is down. 2) Transferee is off hold.

Transitions to TRANSFER_RETRANSFER: 1) TRANSFER_RECALLING: Recall target hangs up or time expires. atxferloopdelay is zero. 2) TRANSFER_WAIT_TO_RETRANSFER: Time expires.

State operation: The original transfer target is requested and is set as the recall target. The recall target is called and placed into the transferee bridge.

Transitions from TRANSFER_RETRANSFER: 1) TRANSFER_FAIL: Transferee hangs up. 2) TRANSFER_WAIT_TO_RECALL: Recall target hangs up or time expires. atxferloopdelay is non-zero. 3) TRANSFER_RECALLING: Recall target hangs up or time expires. atxferloopdelay is zero.

TRANSFER_WAIT_TO_RECALL 

Wait to recall state.

This state is used simply to give a bit of breathing room between attempting to call back the original transfer target and attempting to call back the original transferer. The transferee hears music on hold during this state as an auditory clue that no one is currently being dialed.

Superstate: Recall

Preconditions: 1) Recall target is down. 2) Transferee is off hold.

Transitions to TRANSFER_WAIT_TO_RECALL: 1) TRANSFER_RETRANSFER: Recall target hangs up or time expires. atxferloopdelay is non-zero.

State operation: Transferee is placed on hold.

Transitions from TRANSFER_WAIT_TO_RECALL: 1) TRANSFER_FAIL: Transferee hangs up 2) TRANSFER_RECALLING: Time expires

TRANSFER_FAIL 

Fail state.

This state indicates that something occurred during the transfer that makes a graceful completion impossible. The most common stimulus for this state is when the transferee hangs up.

Superstate: Transfer and Recall

Preconditions: None

Transitions to TRANSFER_FAIL: 1) TRANSFER_CALLING_TARGET: Transferee hangs up. 2) TRANSFER_HESITANT: Transferee hangs up. 3) TRANSFER_DOUBLECHECKING: Transferee hangs up. 4) TRANSFER_BLOND_NONFINAL: Transferee hangs up. 5) TRANSFER_RECALLING: a) Transferee hangs up. b) Recall target hangs up or time expires, and number of recall attempts exceeds atxfercallbackretries. 6) TRANSFER_WAIT_TO_RETRANSFER: Transferee hangs up. 7) TRANSFER_RETRANSFER: Transferee hangs up. 8) TRANSFER_WAIT_TO_RECALL: Transferee hangs up.

State operation: A transfer stasis publication is made indicating a failed transfer. The transferee bridge is destroyed.

Transitions from TRANSFER_FAIL: None.

Definition at line 773 of file bridge_basic.c.

773 {
774 /*!
775 * \brief Calling Target state
776 *
777 * This state describes the initial state of a transfer. The transferer
778 * waits in the transfer target's bridge for the transfer target to answer.
779 *
780 * Superstate: Transfer
781 *
782 * Preconditions:
783 * 1) Transfer target is RINGING
784 * 2) Transferer is in transferee bridge
785 * 3) Transferee is on hold
786 *
787 * Transitions to TRANSFER_CALLING_TARGET:
788 * 1) This is the initial state for an attended transfer.
789 * 2) TRANSFER_HESITANT: Transferer presses DTMF swap sequence
790 *
791 * State operation:
792 * The transferer is moved from the transferee bridge into the transfer
793 * target bridge.
794 *
795 * Transitions from TRANSFER_CALLING_TARGET:
796 * 1) TRANSFER_FAIL: Transferee hangs up.
797 * 2) TRANSFER_BLOND: Transferer hangs up or presses DTMF swap sequence
798 * and configured atxferdropcall setting is yes.
799 * 3) TRANSFER_BLOND_NONFINAL: Transferer hangs up or presses DTMF swap
800 * sequence and configured atxferdropcall setting is no.
801 * 4) TRANSFER_CONSULTING: Transfer target answers the call.
802 * 5) TRANSFER_REBRIDGE: Transfer target hangs up, call to transfer target
803 * times out, or transferer presses DTMF abort sequence.
804 * 6) TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence.
805 * 7) TRANSFER_HESITANT: Transferer presses DTMF swap sequence.
806 */
808 /*!
809 * \brief Hesitant state
810 *
811 * This state only arises if when waiting for the transfer target to
812 * answer, the transferer presses the DTMF swap sequence. This will
813 * cause the transferer to be rebridged with the transferee temporarily.
814 *
815 * Superstate: Transfer
816 *
817 * Preconditions:
818 * 1) Transfer target is in ringing state
819 * 2) Transferer is in transfer target bridge
820 * 3) Transferee is on hold
821 *
822 * Transitions to TRANSFER_HESITANT:
823 * 1) TRANSFER_CALLING_TARGET: Transferer presses DTMF swap sequence.
824 *
825 * State operation:
826 * The transferer is moved from the transfer target bridge into the
827 * transferee bridge, and the transferee is taken off hold.
828 *
829 * Transitions from TRANSFER_HESITANT:
830 * 1) TRANSFER_FAIL: Transferee hangs up
831 * 2) TRANSFER_BLOND: Transferer hangs up or presses DTMF swap sequence
832 * and configured atxferdropcall setting is yes.
833 * 3) TRANSFER_BLOND_NONFINAL: Transferer hangs up or presses DTMF swap
834 * sequence and configured atxferdropcall setting is no.
835 * 4) TRANSFER_DOUBLECHECKING: Transfer target answers the call
836 * 5) TRANSFER_RESUME: Transfer target hangs up, call to transfer target
837 * times out, or transferer presses DTMF abort sequence.
838 * 6) TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence.
839 * 7) TRANSFER_CALLING_TARGET: Transferer presses DTMF swap sequence.
840 */
842 /*!
843 * \brief Rebridge state
844 *
845 * This is a terminal state that indicates that the transferer needs
846 * to move back to the transferee's bridge. This is a failed attended
847 * transfer result.
848 *
849 * Superstate: Transfer
850 *
851 * Preconditions:
852 * 1) Transferer is in transfer target bridge
853 * 2) Transferee is on hold
854 *
855 * Transitions to TRANSFER_REBRIDGE:
856 * 1) TRANSFER_CALLING_TARGET: Transfer target hangs up, call to transfer target
857 * times out, or transferer presses DTMF abort sequence.
858 * 2) TRANSFER_STATE_CONSULTING: Transfer target hangs up, or transferer presses
859 * DTMF abort sequence.
860 *
861 * State operation:
862 * The transferer channel is moved from the transfer target bridge to the
863 * transferee bridge. The transferee is taken off hold. A stasis transfer
864 * message is published indicating a failed attended transfer.
865 *
866 * Transitions from TRANSFER_REBRIDGE:
867 * None
868 */
870 /*!
871 * \brief Resume state
872 *
873 * This is a terminal state that indicates that the party bridged with the
874 * transferee is the final party to be bridged with that transferee. This state
875 * may come about due to a successful recall or due to a failed transfer.
876 *
877 * Superstate: Transfer or Recall
878 *
879 * Preconditions:
880 * In Transfer Superstate:
881 * 1) Transferer is in transferee bridge
882 * 2) Transferee is not on hold
883 * In Recall Superstate:
884 * 1) The recall target is in the transferee bridge
885 * 2) Transferee is not on hold
886 *
887 * Transitions to TRANSFER_RESUME:
888 * TRANSFER_HESITANT: Transfer target hangs up, call to transfer target times out,
889 * or transferer presses DTMF abort sequence.
890 * TRANSFER_DOUBLECHECKING: Transfer target hangs up or transferer presses DTMF
891 * abort sequence.
892 * TRANSFER_BLOND_NONFINAL: Recall target answers
893 * TRANSFER_RECALLING: Recall target answers
894 * TRANSFER_RETRANSFER: Recall target answers
895 *
896 * State operations:
897 * None
898 *
899 * Transitions from TRANSFER_RESUME:
900 * None
901 */
903 /*!
904 * \brief Threeway state
905 *
906 * This state results when the transferer wishes to have all parties involved
907 * in a transfer to be in the same bridge together.
908 *
909 * Superstate: Transfer
910 *
911 * Preconditions:
912 * 1) Transfer target state is either RINGING or UP
913 * 2) Transferer is in either bridge
914 * 3) Transferee is not on hold
915 *
916 * Transitions to TRANSFER_THREEWAY:
917 * 1) TRANSFER_CALLING_TARGET: Transferer presses DTMF threeway sequence.
918 * 2) TRANSFER_HESITANT: Transferer presses DTMF threeway sequence.
919 * 3) TRANSFER_CONSULTING: Transferer presses DTMF threeway sequence.
920 * 4) TRANSFER_DOUBLECHECKING: Transferer presses DTMF threeway sequence.
921 *
922 * State operation:
923 * The transfer target bridge is merged into the transferee bridge.
924 *
925 * Transitions from TRANSFER_THREEWAY:
926 * None.
927 */
929 /*!
930 * \brief Consulting state
931 *
932 * This state describes the case where the transferer and transfer target
933 * are able to converse in the transfer target's bridge prior to completing
934 * the transfer.
935 *
936 * Superstate: Transfer
937 *
938 * Preconditions:
939 * 1) Transfer target is UP
940 * 2) Transferer is in target bridge
941 * 3) Transferee is on hold
942 *
943 * Transitions to TRANSFER_CONSULTING:
944 * 1) TRANSFER_CALLING_TARGET: Transfer target answers.
945 * 2) TRANSFER_DOUBLECHECKING: Transferer presses DTMF swap sequence.
946 *
947 * State operations:
948 * None.
949 *
950 * Transitions from TRANSFER_CONSULTING:
951 * TRANSFER_COMPLETE: Transferer hangs up or transferer presses DTMF complete sequence.
952 * TRANSFER_REBRIDGE: Transfer target hangs up or transferer presses DTMF abort sequence.
953 * TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence.
954 * TRANSFER_DOUBLECHECKING: Transferer presses DTMF swap sequence.
955 */
957 /*!
958 * \brief Double-checking state
959 *
960 * This state describes the case where the transferer and transferee are
961 * able to converse in the transferee's bridge prior to completing the transfer. The
962 * difference between this and TRANSFER_HESITANT is that the transfer target is
963 * UP in this case.
964 *
965 * Superstate: Transfer
966 *
967 * Preconditions:
968 * 1) Transfer target is UP and on hold
969 * 2) Transferer is in transferee bridge
970 * 3) Transferee is off hold
971 *
972 * Transitions to TRANSFER_DOUBLECHECKING:
973 * 1) TRANSFER_HESITANT: Transfer target answers.
974 * 2) TRANSFER_CONSULTING: Transferer presses DTMF swap sequence.
975 *
976 * State operations:
977 * None.
978 *
979 * Transitions from TRANSFER_DOUBLECHECKING:
980 * 1) TRANSFER_FAIL: Transferee hangs up.
981 * 2) TRANSFER_COMPLETE: Transferer hangs up or presses DTMF complete sequence.
982 * 3) TRANSFER_RESUME: Transfer target hangs up or transferer presses DTMF abort sequence.
983 * 4) TRANSFER_THREEWAY: Transferer presses DTMF threeway sequence.
984 * 5) TRANSFER_CONSULTING: Transferer presses the DTMF swap sequence.
985 */
987 /*!
988 * \brief Complete state
989 *
990 * This is a terminal state where a transferer has successfully completed an attended
991 * transfer. This state's goal is to get the transfer target and transferee into
992 * the same bridge and the transferer off the call.
993 *
994 * Superstate: Transfer
995 *
996 * Preconditions:
997 * 1) Transfer target is UP and off hold.
998 * 2) Transferer is in either bridge.
999 * 3) Transferee is off hold.
1000 *
1001 * Transitions to TRANSFER_COMPLETE:
1002 * 1) TRANSFER_CONSULTING: transferer hangs up or presses the DTMF complete sequence.
1003 * 2) TRANSFER_DOUBLECHECKING: transferer hangs up or presses the DTMF complete sequence.
1004 *
1005 * State operation:
1006 * The transfer target bridge is merged into the transferee bridge. The transferer
1007 * channel is kicked out of the bridges as part of the merge.
1008 *
1009 * State operations:
1010 * 1) Merge the transfer target bridge into the transferee bridge,
1011 * excluding the transferer channel from the merge.
1012 * 2) Publish a stasis transfer message.
1013 *
1014 * Exit operations:
1015 * This is a terminal state, so there are no exit operations.
1016 */
1018 /*!
1019 * \brief Blond state
1020 *
1021 * This is a terminal state where a transferer has completed an attended transfer prior
1022 * to the transfer target answering. This state is only entered if atxferdropcall
1023 * is set to 'yes'. This is considered to be a successful attended transfer.
1024 *
1025 * Superstate: Transfer
1026 *
1027 * Preconditions:
1028 * 1) Transfer target is RINGING.
1029 * 2) Transferer is in either bridge.
1030 * 3) Transferee is off hold.
1031 *
1032 * Transitions to TRANSFER_BLOND:
1033 * 1) TRANSFER_CALLING_TARGET: Transferer hangs up or presses the DTMF complete sequence.
1034 * atxferdropcall is set to 'yes'.
1035 * 2) TRANSFER_HESITANT: Transferer hangs up or presses the DTMF complete sequence.
1036 * atxferdropcall is set to 'yes'.
1037 *
1038 * State operations:
1039 * The transfer target bridge is merged into the transferee bridge. The transferer
1040 * channel is kicked out of the bridges as part of the merge. A stasis transfer
1041 * publication is sent indicating a successful transfer.
1042 *
1043 * Transitions from TRANSFER_BLOND:
1044 * None
1045 */
1047 /*!
1048 * \brief Blond non-final state
1049 *
1050 * This state is very similar to the TRANSFER_BLOND state, except that
1051 * this state is entered when atxferdropcall is set to 'no'. This is the
1052 * initial state of the Recall superstate, so state operations mainly involve
1053 * moving to the Recall superstate. This means that the transfer target, that
1054 * is currently ringing is now known as the recall target.
1055 *
1056 * Superstate: Recall
1057 *
1058 * Preconditions:
1059 * 1) Recall target is RINGING.
1060 * 2) Transferee is off hold.
1061 *
1062 * Transitions to TRANSFER_BLOND_NONFINAL:
1063 * 1) TRANSFER_CALLING_TARGET: Transferer hangs up or presses the DTMF complete sequence.
1064 * atxferdropcall is set to 'no'.
1065 * 2) TRANSFER_HESITANT: Transferer hangs up or presses the DTMF complete sequence.
1066 * atxferdropcall is set to 'no'.
1067 *
1068 * State operation:
1069 * The superstate of the attended transfer is changed from Transfer to Recall.
1070 * The transfer target bridge is merged into the transferee bridge. The transferer
1071 * channel is kicked out of the bridges as part of the merge.
1072 *
1073 * Transitions from TRANSFER_BLOND_NONFINAL:
1074 * 1) TRANSFER_FAIL: Transferee hangs up
1075 * 2) TRANSFER_RESUME: Recall target answers
1076 * 3) TRANSFER_RECALLING: Recall target hangs up or time expires.
1077 */
1079 /*!
1080 * \brief Recalling state
1081 *
1082 * This state is entered if the recall target from the TRANSFER_BLOND_NONFINAL
1083 * or TRANSFER_RETRANSFER states hangs up or does not answer. The goal of this
1084 * state is to call back the original transferer in an attempt to recover the
1085 * original call.
1086 *
1087 * Superstate: Recall
1088 *
1089 * Preconditions:
1090 * 1) Recall target is down.
1091 * 2) Transferee is off hold.
1092 *
1093 * Transitions to TRANSFER_RECALLING:
1094 * 1) TRANSFER_BLOND_NONFINAL: Recall target hangs up or time expires.
1095 * 2) TRANSFER_RETRANSFER: Recall target hangs up or time expires.
1096 * atxferloopdelay is non-zero.
1097 * 3) TRANSFER_WAIT_TO_RECALL: Time expires.
1098 *
1099 * State operation:
1100 * The original transferer becomes the recall target and is called using the Dialing API.
1101 * Ringing is indicated to the transferee.
1102 *
1103 * Transitions from TRANSFER_RECALLING:
1104 * 1) TRANSFER_FAIL:
1105 * a) Transferee hangs up.
1106 * b) Recall target hangs up or time expires, and number of recall attempts exceeds atxfercallbackretries
1107 * 2) TRANSFER_WAIT_TO_RETRANSFER: Recall target hangs up or time expires.
1108 * atxferloopdelay is non-zero.
1109 * 3) TRANSFER_RETRANSFER: Recall target hangs up or time expires.
1110 * atxferloopdelay is zero.
1111 * 4) TRANSFER_RESUME: Recall target answers.
1112 */
1114 /*!
1115 * \brief Wait to Retransfer state
1116 *
1117 * This state is used simply to give a bit of breathing room between attempting
1118 * to call back the original transferer and attempting to call back the original
1119 * transfer target. The transferee hears music on hold during this state as an
1120 * auditory clue that no one is currently being dialed.
1121 *
1122 * Superstate: Recall
1123 *
1124 * Preconditions:
1125 * 1) Recall target is down.
1126 * 2) Transferee is off hold.
1127 *
1128 * Transitions to TRANSFER_WAIT_TO_RETRANSFER:
1129 * 1) TRANSFER_RECALLING: Recall target hangs up or time expires.
1130 * atxferloopdelay is non-zero.
1131 *
1132 * State operation:
1133 * The transferee is placed on hold.
1134 *
1135 * Transitions from TRANSFER_WAIT_TO_RETRANSFER:
1136 * 1) TRANSFER_FAIL: Transferee hangs up.
1137 * 2) TRANSFER_RETRANSFER: Time expires.
1138 */
1140 /*!
1141 * \brief Retransfer state
1142 *
1143 * This state is used in order to attempt to call back the original
1144 * transfer target channel from the transfer. The transferee hears
1145 * ringing during this state as an auditory cue that a party is being
1146 * dialed.
1147 *
1148 * Superstate: Recall
1149 *
1150 * Preconditions:
1151 * 1) Recall target is down.
1152 * 2) Transferee is off hold.
1153 *
1154 * Transitions to TRANSFER_RETRANSFER:
1155 * 1) TRANSFER_RECALLING: Recall target hangs up or time expires.
1156 * atxferloopdelay is zero.
1157 * 2) TRANSFER_WAIT_TO_RETRANSFER: Time expires.
1158 *
1159 * State operation:
1160 * The original transfer target is requested and is set as the recall target.
1161 * The recall target is called and placed into the transferee bridge.
1162 *
1163 * Transitions from TRANSFER_RETRANSFER:
1164 * 1) TRANSFER_FAIL: Transferee hangs up.
1165 * 2) TRANSFER_WAIT_TO_RECALL: Recall target hangs up or time expires.
1166 * atxferloopdelay is non-zero.
1167 * 3) TRANSFER_RECALLING: Recall target hangs up or time expires.
1168 * atxferloopdelay is zero.
1169 */
1171 /*!
1172 * \brief Wait to recall state
1173 *
1174 * This state is used simply to give a bit of breathing room between attempting
1175 * to call back the original transfer target and attempting to call back the
1176 * original transferer. The transferee hears music on hold during this state as an
1177 * auditory clue that no one is currently being dialed.
1178 *
1179 * Superstate: Recall
1180 *
1181 * Preconditions:
1182 * 1) Recall target is down.
1183 * 2) Transferee is off hold.
1184 *
1185 * Transitions to TRANSFER_WAIT_TO_RECALL:
1186 * 1) TRANSFER_RETRANSFER: Recall target hangs up or time expires.
1187 * atxferloopdelay is non-zero.
1188 *
1189 * State operation:
1190 * Transferee is placed on hold.
1191 *
1192 * Transitions from TRANSFER_WAIT_TO_RECALL:
1193 * 1) TRANSFER_FAIL: Transferee hangs up
1194 * 2) TRANSFER_RECALLING: Time expires
1195 */
1197 /*!
1198 * \brief Fail state
1199 *
1200 * This state indicates that something occurred during the transfer that
1201 * makes a graceful completion impossible. The most common stimulus for this
1202 * state is when the transferee hangs up.
1203 *
1204 * Superstate: Transfer and Recall
1205 *
1206 * Preconditions:
1207 * None
1208 *
1209 * Transitions to TRANSFER_FAIL:
1210 * 1) TRANSFER_CALLING_TARGET: Transferee hangs up.
1211 * 2) TRANSFER_HESITANT: Transferee hangs up.
1212 * 3) TRANSFER_DOUBLECHECKING: Transferee hangs up.
1213 * 4) TRANSFER_BLOND_NONFINAL: Transferee hangs up.
1214 * 5) TRANSFER_RECALLING:
1215 * a) Transferee hangs up.
1216 * b) Recall target hangs up or time expires, and number of
1217 * recall attempts exceeds atxfercallbackretries.
1218 * 6) TRANSFER_WAIT_TO_RETRANSFER: Transferee hangs up.
1219 * 7) TRANSFER_RETRANSFER: Transferee hangs up.
1220 * 8) TRANSFER_WAIT_TO_RECALL: Transferee hangs up.
1221 *
1222 * State operation:
1223 * A transfer stasis publication is made indicating a failed transfer.
1224 * The transferee bridge is destroyed.
1225 *
1226 * Transitions from TRANSFER_FAIL:
1227 * None.
1228 */
1230};
@ TRANSFER_WAIT_TO_RETRANSFER
Wait to Retransfer state.
@ TRANSFER_DOUBLECHECKING
Double-checking state.
Definition: bridge_basic.c:986
@ TRANSFER_COMPLETE
Complete state.
@ TRANSFER_REBRIDGE
Rebridge state.
Definition: bridge_basic.c:869
@ TRANSFER_RETRANSFER
Retransfer state.
@ TRANSFER_FAIL
Fail state.
@ TRANSFER_WAIT_TO_RECALL
Wait to recall state.
@ TRANSFER_HESITANT
Hesitant state.
Definition: bridge_basic.c:841
@ TRANSFER_BLOND
Blond state.
@ TRANSFER_RESUME
Resume state.
Definition: bridge_basic.c:902
@ TRANSFER_THREEWAY
Threeway state.
Definition: bridge_basic.c:928
@ TRANSFER_CALLING_TARGET
Calling Target state.
Definition: bridge_basic.c:807
@ TRANSFER_CONSULTING
Consulting state.
Definition: bridge_basic.c:956
@ TRANSFER_RECALLING
Recalling state.
@ TRANSFER_BLOND_NONFINAL
Blond non-final state.

◆ attended_transfer_state_flags

Flags that indicate properties of attended transfer states.

Enumerator
TRANSFER_STATE_FLAG_TIMER_RESET 

This state requires that the timer be reset when entering the state

TRANSFER_STATE_FLAG_TIMER_LOOP_DELAY 

This state's timer uses atxferloopdelay

TRANSFER_STATE_FLAG_ATXFER_NO_ANSWER 

This state's timer uses atxfernoanswertimeout

TRANSFER_STATE_FLAG_TIMED 

This state has a time limit associated with it

TRANSFER_STATE_FLAG_TERMINAL 

This state does not transition to any other states

Definition at line 1949 of file bridge_basic.c.

1949 {
1950 /*! This state requires that the timer be reset when entering the state */
1952 /*! This state's timer uses atxferloopdelay */
1954 /*! This state's timer uses atxfernoanswertimeout */
1956 /*! This state has a time limit associated with it */
1959 /*! This state does not transition to any other states */
1961};
@ TRANSFER_STATE_FLAG_TIMER_RESET
@ TRANSFER_STATE_FLAG_TIMED
@ TRANSFER_STATE_FLAG_TERMINAL
@ TRANSFER_STATE_FLAG_ATXFER_NO_ANSWER
@ TRANSFER_STATE_FLAG_TIMER_LOOP_DELAY

◆ attended_transfer_stimulus

Stimuli that can cause transfer state changes.

Enumerator
STIMULUS_NONE 

No stimulus. This literally can never happen.

STIMULUS_TRANSFEREE_HANGUP 

All of the transferee channels have been hung up.

STIMULUS_TRANSFERER_HANGUP 

The transferer has hung up.

STIMULUS_TRANSFER_TARGET_HANGUP 

The transfer target channel has hung up.

STIMULUS_TRANSFER_TARGET_ANSWER 

The transfer target channel has answered.

STIMULUS_RECALL_TARGET_HANGUP 

The recall target channel has hung up.

STIMULUS_RECALL_TARGET_ANSWER 

The recall target channel has answered.

STIMULUS_TIMEOUT 

The current state's timer has expired.

STIMULUS_DTMF_ATXFER_ABORT 

The transferer pressed the abort DTMF sequence.

STIMULUS_DTMF_ATXFER_COMPLETE 

The transferer pressed the complete DTMF sequence.

STIMULUS_DTMF_ATXFER_THREEWAY 

The transferer pressed the three-way DTMF sequence.

STIMULUS_DTMF_ATXFER_SWAP 

The transferer pressed the swap DTMF sequence.

Definition at line 1235 of file bridge_basic.c.

1235 {
1236 /*! No stimulus. This literally can never happen. */
1238 /*! All of the transferee channels have been hung up. */
1240 /*! The transferer has hung up. */
1242 /*! The transfer target channel has hung up. */
1244 /*! The transfer target channel has answered. */
1246 /*! The recall target channel has hung up. */
1248 /*! The recall target channel has answered. */
1250 /*! The current state's timer has expired. */
1252 /*! The transferer pressed the abort DTMF sequence. */
1254 /*! The transferer pressed the complete DTMF sequence. */
1256 /*! The transferer pressed the three-way DTMF sequence. */
1258 /*! The transferer pressed the swap DTMF sequence. */
1260};
@ STIMULUS_RECALL_TARGET_HANGUP
@ STIMULUS_RECALL_TARGET_ANSWER
@ STIMULUS_TRANSFER_TARGET_HANGUP
@ STIMULUS_TRANSFEREE_HANGUP
@ STIMULUS_DTMF_ATXFER_THREEWAY
@ STIMULUS_DTMF_ATXFER_ABORT
@ STIMULUS_TRANSFER_TARGET_ANSWER
@ STIMULUS_TRANSFERER_HANGUP
@ STIMULUS_DTMF_ATXFER_COMPLETE
@ STIMULUS_DTMF_ATXFER_SWAP
@ STIMULUS_TIMEOUT
@ STIMULUS_NONE

◆ attended_transfer_superstate

Attended transfer superstates.

An attended transfer's progress is facilitated by a state machine. The individual states of the state machine fall into the realm of one of two superstates.

Enumerator
SUPERSTATE_TRANSFER 

Transfer superstate.

The attended transfer state machine begins in this superstate. The goal of this state is for a transferer channel to facilitate a transfer from a transferee to a transfer target.

There are two bridges used in this superstate. The transferee bridge is the bridge that the transferer and transferee channels originally communicate in, and the target bridge is the bridge where the transfer target is being dialed.

The transferer channel is capable of moving between the bridges using the DTMF swap sequence.

SUPERSTATE_RECALL 

Recall superstate.

The attended transfer state machine moves to this superstate if atxferdropcall is set to "no" and the transferer channel hangs up during a transfer. The goal in this superstate is to call back either the transfer target or transferer and rebridge with the transferee channel(s).

In this superstate, there is only a single bridge used, the original transferee bridge. Rather than distinguishing between a transferer and transfer target, all outbound calls are toward a "recall_target" channel.

Definition at line 736 of file bridge_basic.c.

736 {
737 /*!
738 * \brief Transfer superstate
739 *
740 * The attended transfer state machine begins in this superstate. The
741 * goal of this state is for a transferer channel to facilitate a
742 * transfer from a transferee to a transfer target.
743 *
744 * There are two bridges used in this superstate. The transferee bridge is
745 * the bridge that the transferer and transferee channels originally
746 * communicate in, and the target bridge is the bridge where the transfer
747 * target is being dialed.
748 *
749 * The transferer channel is capable of moving between the bridges using
750 * the DTMF swap sequence.
751 */
753 /*!
754 * \brief Recall superstate
755 *
756 * The attended transfer state machine moves to this superstate if
757 * atxferdropcall is set to "no" and the transferer channel hangs up
758 * during a transfer. The goal in this superstate is to call back either
759 * the transfer target or transferer and rebridge with the transferee
760 * channel(s).
761 *
762 * In this superstate, there is only a single bridge used, the original
763 * transferee bridge. Rather than distinguishing between a transferer
764 * and transfer target, all outbound calls are toward a "recall_target"
765 * channel.
766 */
768};
@ SUPERSTATE_TRANSFER
Transfer superstate.
Definition: bridge_basic.c:752
@ SUPERSTATE_RECALL
Recall superstate.
Definition: bridge_basic.c:767

◆ bridge_basic_personality_type

Enumerator
BRIDGE_BASIC_PERSONALITY_NORMAL 

Index for "normal" basic bridge personality

BRIDGE_BASIC_PERSONALITY_ATXFER 

Index for attended transfer basic bridge personality

BRIDGE_BASIC_PERSONALITY_END 

Indicates end of enum. Must always remain the last element

Definition at line 58 of file bridge_basic.c.

58 {
59 /*! Index for "normal" basic bridge personality */
61 /*! Index for attended transfer basic bridge personality */
63 /*! Indicates end of enum. Must always remain the last element */
65};
@ BRIDGE_BASIC_PERSONALITY_NORMAL
Definition: bridge_basic.c:60
@ BRIDGE_BASIC_PERSONALITY_ATXFER
Definition: bridge_basic.c:62
@ BRIDGE_BASIC_PERSONALITY_END
Definition: bridge_basic.c:64

Function Documentation

◆ add_normal_hooks()

static int add_normal_hooks ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 640 of file bridge_basic.c.

641{
642 return ast_bridge_hangup_hook(bridge_channel->features, basic_hangup_hook,
644 || bridge_basic_setup_features(bridge_channel);
645}
static int basic_hangup_hook(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Definition: bridge_basic.c:290
static int bridge_basic_setup_features(struct ast_bridge_channel *bridge_channel)
Definition: bridge_basic.c:630
int ast_bridge_hangup_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a hangup hook to a bridge features structure.
Definition: bridge.c:3265
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
#define NULL
Definition: resample.c:96
struct ast_bridge_features * features

References ast_bridge_hangup_hook(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, basic_hangup_hook(), bridge_basic_setup_features(), ast_bridge_channel::features, and NULL.

Referenced by bridge_personality_normal_push(), and on_personality_change_normal().

◆ add_transferer_role()

static int add_transferer_role ( struct ast_channel chan,
struct ast_bridge_features_attended_transfer attended_transfer 
)
static

Definition at line 3135 of file bridge_basic.c.

3136{
3137 const char *atxfer_abort;
3138 const char *atxfer_threeway;
3139 const char *atxfer_complete;
3140 const char *atxfer_swap;
3141 struct ast_features_xfer_config *xfer_cfg;
3142 SCOPED_CHANNELLOCK(lock, chan);
3143
3144 xfer_cfg = ast_get_chan_features_xfer_config(chan);
3145 if (!xfer_cfg) {
3146 return -1;
3147 }
3148 if (attended_transfer) {
3149 atxfer_abort = ast_strdupa(S_OR(attended_transfer->abort, xfer_cfg->atxferabort));
3150 atxfer_threeway = ast_strdupa(S_OR(attended_transfer->threeway, xfer_cfg->atxferthreeway));
3151 atxfer_complete = ast_strdupa(S_OR(attended_transfer->complete, xfer_cfg->atxfercomplete));
3152 atxfer_swap = ast_strdupa(S_OR(attended_transfer->swap, xfer_cfg->atxferswap));
3153 } else {
3157 atxfer_swap = ast_strdupa(xfer_cfg->atxferswap);
3158 }
3159 ao2_ref(xfer_cfg, -1);
3160
3166}
ast_mutex_t lock
Definition: app_sla.c:331
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static int atxfer_complete(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
DTMF hook when transferer presses complete sequence.
static int atxfer_abort(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
DTMF hook when transferer presses abort sequence.
static int atxfer_swap(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
DTMF hook when transferer presses swap sequence.
static int atxfer_threeway(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
DTMF hook when transferer presses threeway sequence.
#define AST_TRANSFERER_ROLE_NAME
Definition: bridge_basic.h:36
int ast_channel_set_bridge_role_option(struct ast_channel *channel, const char *role_name, const char *option, const char *value)
Set a role option on a channel.
Definition: bridge_roles.c:375
int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name)
Adds a bridge role to a channel.
Definition: bridge_roles.c:313
struct ast_features_xfer_config * ast_get_chan_features_xfer_config(struct ast_channel *chan)
Get the transfer configuration options for a channel.
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
char swap[MAXIMUM_DTMF_FEATURE_STRING]
char threeway[MAXIMUM_DTMF_FEATURE_STRING]
char complete[MAXIMUM_DTMF_FEATURE_STRING]
char abort[MAXIMUM_DTMF_FEATURE_STRING]
Feature configuration relating to transfers.

References ast_bridge_features_attended_transfer::abort, ao2_ref, ast_channel_add_bridge_role(), ast_channel_set_bridge_role_option(), ast_get_chan_features_xfer_config(), ast_strdupa, AST_TRANSFERER_ROLE_NAME, atxfer_abort(), atxfer_complete(), atxfer_swap(), atxfer_threeway(), ast_features_xfer_config::atxferabort, ast_features_xfer_config::atxfercomplete, ast_features_xfer_config::atxferswap, ast_features_xfer_config::atxferthreeway, ast_bridge_features_attended_transfer::complete, lock, S_OR, SCOPED_CHANNELLOCK, ast_bridge_features_attended_transfer::swap, and ast_bridge_features_attended_transfer::threeway.

Referenced by feature_attended_transfer().

◆ ast_bridge_basic_new()

struct ast_bridge * ast_bridge_basic_new ( void  )

Create a new basic class bridge.

Returns
a pointer to a new bridge on success
Return values
NULLon failure

Example usage:

struct ast_bridge *bridge;
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
Structure that contains information about a bridge.
Definition: bridge.h:349

This creates a basic two party bridge with any configured DTMF features enabled that will be destroyed once one of the channels hangs up.

Definition at line 3655 of file bridge_basic.c.

3656{
3657 struct ast_bridge *bridge;
3658
3659 bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_basic_v_table);
3660 bridge = bridge_base_init(bridge,
3663 bridge = bridge_basic_personality_alloc(bridge);
3664 bridge = bridge_register(bridge);
3665 return bridge;
3666}
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition: bridge.h:94
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition: bridge.h:90
@ AST_BRIDGE_CAPABILITY_1TO1MIX
Definition: bridge.h:92
struct ast_bridge_methods ast_bridge_basic_v_table
Bridge basic class virtual method table.
static struct ast_bridge * bridge_basic_personality_alloc(struct ast_bridge *bridge)
#define NORMAL_FLAGS
Definition: bridge_basic.c:51
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:691
struct ast_bridge * bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Initialize the base class of the bridge.
Definition: bridge.c:742
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:706

References ast_bridge_basic_v_table, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_CAPABILITY_NATIVE, bridge_alloc(), bridge_base_init(), bridge_basic_personality_alloc(), bridge_register(), NORMAL_FLAGS, and NULL.

Referenced by action_bridge(), agent_request_exec(), ast_bridge_call_with_flags(), AST_TEST_DEFINE(), bridge_exec(), feature_attended_transfer(), and parked_call_app_exec().

◆ ast_bridge_basic_set_flags()

void ast_bridge_basic_set_flags ( struct ast_bridge bridge,
unsigned int  flags 
)

Set feature flags on a basic bridge.

Using this function instead of setting flags directly will ensure that after operations such as an attended transfer, the bridge will maintain the flags that were set on it.

Parameters
bridge
flagsThese are added to the flags already set.

Definition at line 3668 of file bridge_basic.c.

3669{
3671 struct bridge_basic_personality *personality = bridge->personality;
3672
3673 personality->details[personality->current].bridge_flags |= flags;
3674 ast_set_flag(&bridge->feature_flags, flags);
3675}
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:583
void * personality
Definition: bridge.h:353
struct ast_flags feature_flags
Definition: bridge.h:369
structure that organizes different personalities for basic bridges.
Definition: bridge_basic.c:327
enum bridge_basic_personality_type current
Definition: bridge_basic.c:329
struct personality_details details[BRIDGE_BASIC_PERSONALITY_END]
Definition: bridge_basic.c:331
unsigned int bridge_flags
Definition: bridge_basic.c:317
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ast_bridge_lock, ast_bridge_unlock, ast_set_flag, personality_details::bridge_flags, bridge_basic_personality::current, bridge_basic_personality::details, ast_bridge::feature_flags, lock, ast_bridge::personality, and SCOPED_LOCK.

Referenced by ast_bridge_call_with_flags().

◆ ast_bridge_features_ds_append()

int ast_bridge_features_ds_append ( struct ast_channel chan,
struct ast_flags flags 
)

Append basic bridge DTMF feature flags on the channel.

Since
12.0.0
Parameters
chanChannel to append DTMF features datastore.
flagsBuiltin DTMF feature flags. (ast_bridge_config flags)
Note
The channel must be locked before calling this function.
This function differs from ast_bridge_features_ds_set only in that it won't remove features already set on the channel.
Return values
0on success.
-1on error.

Definition at line 263 of file bridge_basic.c.

264{
265 return bridge_features_ds_set_full(chan, flags, 0);
266}
static int bridge_features_ds_set_full(struct ast_channel *chan, struct ast_flags *flags, int replace)
Definition: bridge_basic.c:224

References bridge_features_ds_set_full(), and ast_flags::flags.

Referenced by pre_bridge_setup().

◆ ast_bridge_features_ds_get()

struct ast_flags * ast_bridge_features_ds_get ( struct ast_channel chan)

Get DTMF feature flags from the channel.

Since
12.0.0
Parameters
chanChannel to get DTMF features datastore.
Note
The channel should be locked before calling this function.
The channel must remain locked until the flags returned have been consumed.
Returns
flags on success.
Return values
NULLif the datastore does not exist.

Definition at line 268 of file bridge_basic.c.

269{
270 struct ast_datastore *datastore;
271
273 if (!datastore) {
274 return NULL;
275 }
276 return datastore->data;
277}
static const struct ast_datastore_info dtmf_features_info
Definition: bridge_basic.c:82
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66

References ast_channel_datastore_find(), ast_datastore::data, dtmf_features_info, and NULL.

Referenced by ast_bridge_features_ds_get_string(), attended_transfer_properties_alloc(), parked_call_retrieve_enable_features(), and setup_bridge_features_builtin().

◆ ast_bridge_features_ds_get_string()

int ast_bridge_features_ds_get_string ( struct ast_channel chan,
char *  buffer,
size_t  buf_size 
)

writes a channel's DTMF features to a buffer string

Since
12.0.0
Parameters
chanchannel whose feature flags should be checked
bufferpointer string buffer where the output should be stored
buf_sizesize of the provided buffer (ideally enough for all features, 6+)
Return values
0on successful write
-1on failure

Definition at line 208 of file bridge_basic.c.

209{
210 struct ast_flags *channel_flags;
211 struct ast_flags held_copy;
212
213 ast_channel_lock(chan);
214 if (!(channel_flags = ast_bridge_features_ds_get(chan))) {
215 ast_channel_unlock(chan);
216 return -1;
217 }
218 held_copy = *channel_flags;
219 ast_channel_unlock(chan);
220
221 return dtmf_features_flags_to_string(&held_copy, buffer, buf_size);
222}
static int dtmf_features_flags_to_string(struct ast_flags *feature_flags, char *buffer, size_t buffer_size)
Definition: bridge_basic.c:133
struct ast_flags * ast_bridge_features_ds_get(struct ast_channel *chan)
Get DTMF feature flags from the channel.
Definition: bridge_basic.c:268
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
Structure used to handle boolean flags.
Definition: utils.h:199

References ast_bridge_features_ds_get(), ast_channel_lock, ast_channel_unlock, and dtmf_features_flags_to_string().

Referenced by func_channel_read().

◆ ast_bridge_features_ds_set()

int ast_bridge_features_ds_set ( struct ast_channel chan,
struct ast_flags flags 
)

Set basic bridge DTMF feature flags datastore on the channel.

Since
12.0.0
Parameters
chanChannel to set DTMF features datastore.
flagsBuiltin DTMF feature flags. (ast_bridge_config flags)
Note
The channel must be locked before calling this function.
Return values
0on success.
-1on error.

Definition at line 258 of file bridge_basic.c.

259{
260 return bridge_features_ds_set_full(chan, flags, 1);
261}

References bridge_features_ds_set_full(), and ast_flags::flags.

Referenced by ast_bridge_features_ds_set_string(), parked_call_retrieve_enable_features(), and recalling_exit().

◆ ast_bridge_features_ds_set_string()

int ast_bridge_features_ds_set_string ( struct ast_channel chan,
const char *  features 
)

Sets the features a channel will use upon being bridged.

Since
12.0.0
Parameters
chanWhich channel to set features for
featuresWhich feature codes to set for the channel
Return values
0on success
-1on failure

Definition at line 189 of file bridge_basic.c.

190{
191 struct ast_flags flags = {0};
192
193 if (build_dtmf_features(&flags, features)) {
194 return -1;
195 }
196
197 ast_channel_lock(chan);
198 if (ast_bridge_features_ds_set(chan, &flags)) {
199 ast_channel_unlock(chan);
200 ast_log(LOG_ERROR, "Failed to apply features datastore for '%s' to channel '%s'\n", features, ast_channel_name(chan));
201 return -1;
202 }
203 ast_channel_unlock(chan);
204
205 return 0;
206}
#define ast_log
Definition: astobj2.c:42
static int build_dtmf_features(struct ast_flags *flags, const char *features)
Definition: bridge_basic.c:162
int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags)
Set basic bridge DTMF feature flags datastore on the channel.
Definition: bridge_basic.c:258
const char * ast_channel_name(const struct ast_channel *chan)
#define LOG_ERROR
unsigned int flags
Definition: utils.h:200

References ast_bridge_features_ds_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_log, build_dtmf_features(), ast_flags::flags, and LOG_ERROR.

Referenced by func_channel_write_real().

◆ ast_bridging_init_basic()

void ast_bridging_init_basic ( void  )

Initialize the basic bridge class for use by the system.

Definition at line 3677 of file bridge_basic.c.

3678{
3679 /* Setup bridge basic subclass v_table. */
3685
3686 /*
3687 * Personality vtables don't have the same rules as
3688 * normal bridge vtables. These vtable functions are
3689 * used as alterations to the ast_bridge_basic_v_table
3690 * method functionality and are checked for NULL before
3691 * calling.
3692 */
3695
3696 personality_atxfer_v_table.name = "attended transfer";
3699
3702}
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:923
static int feature_blind_transfer(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Internal built in feature for blind transfers.
static void bridge_basic_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
Definition: bridge_basic.c:687
static void bridge_personality_atxfer_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
static void bridge_basic_destroy(struct ast_bridge *self)
Definition: bridge_basic.c:702
struct ast_bridge_methods personality_normal_v_table
static int bridge_personality_normal_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
Definition: bridge_basic.c:661
static int bridge_basic_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
Definition: bridge_basic.c:670
struct ast_bridge_methods personality_atxfer_v_table
static int bridge_personality_atxfer_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Internal built in feature for attended transfers.
@ AST_BRIDGE_BUILTIN_BLINDTRANSFER
@ AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER
int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf)
Register a handler for a built in feature.
Definition: bridge.c:3062
ast_bridge_push_channel_fn push
Definition: bridge.h:265
const char * name
Definition: bridge.h:259
ast_bridge_destructor_fn destroy
Definition: bridge.h:261
ast_bridge_pull_channel_fn pull
Definition: bridge.h:267

References ast_bridge_base_v_table, ast_bridge_basic_v_table, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, AST_BRIDGE_BUILTIN_BLINDTRANSFER, ast_bridge_features_register(), bridge_basic_destroy(), bridge_basic_pull(), bridge_basic_push(), bridge_personality_atxfer_pull(), bridge_personality_atxfer_push(), bridge_personality_normal_push(), ast_bridge_methods::destroy, feature_attended_transfer(), feature_blind_transfer(), ast_bridge_methods::name, NULL, personality_atxfer_v_table, personality_normal_v_table, ast_bridge_methods::pull, and ast_bridge_methods::push.

Referenced by ast_bridging_init().

◆ attach_framehook()

static int attach_framehook ( struct attended_transfer_properties props,
struct ast_channel channel 
)
static

Definition at line 3112 of file bridge_basic.c.

3113{
3114 struct ast_framehook_interface target_interface = {
3116 .event_cb = transfer_target_framehook_cb,
3119 .disable_inheritance = 1,
3120 };
3121
3122 ao2_ref(props, +1);
3123 target_interface.data = props;
3124
3125 ast_channel_lock(channel);
3126 props->target_framehook_id = ast_framehook_attach(channel, &target_interface);
3127 ast_channel_unlock(channel);
3128 if (props->target_framehook_id == -1) {
3129 ao2_ref(props, -1);
3130 return -1;
3131 }
3132 return 0;
3133}
static void transfer_target_framehook_destroy_cb(void *data)
static struct ast_frame * transfer_target_framehook_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
Frame hook for transfer target channel.
static int transfer_target_framehook_consume(void *data, enum ast_frame_type type)
Callback function which informs upstream if we are consuming a frame of a specific type.
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227

References ao2_ref, ast_channel_lock, ast_channel_unlock, ast_framehook_attach(), AST_FRAMEHOOK_INTERFACE_VERSION, ast_framehook_interface::data, attended_transfer_properties::target_framehook_id, transfer_target_framehook_cb(), transfer_target_framehook_consume(), transfer_target_framehook_destroy_cb(), and ast_framehook_interface::version.

Referenced by feature_attended_transfer(), and retransfer_enter().

◆ attended_transfer_monitor_thread()

static void * attended_transfer_monitor_thread ( void *  data)
static

The main loop for the attended transfer monitor thread.

This loop runs continuously until the attended transfer reaches a terminal state. Stimuli for changes in the attended transfer state are handled in this thread so that all factors in an attended transfer can be handled in an orderly fashion.

Parameters
dataThe attended transfer properties

Definition at line 3058 of file bridge_basic.c.

3059{
3060 struct attended_transfer_properties *props = data;
3061 ast_callid callid;
3062
3063 /*
3064 * Set thread callid to the transferer's callid because we
3065 * are doing all this on that channel's behalf.
3066 */
3068 callid = ast_channel_callid(props->transferer);
3070 if (callid) {
3072 }
3073
3074 for (;;) {
3075 enum attended_transfer_stimulus stimulus;
3076
3077 ast_debug(1, "About to enter state %s for attended transfer %p\n", state_properties[props->state].state_name, props);
3078
3079 if (state_properties[props->state].enter &&
3080 state_properties[props->state].enter(props)) {
3081 ast_log(LOG_ERROR, "State %s enter function returned an error for attended transfer %p\n",
3082 state_properties[props->state].state_name, props);
3083 break;
3084 }
3085
3087 ast_debug(1, "State %s is a terminal state. Ending attended transfer %p\n",
3088 state_properties[props->state].state_name, props);
3089 break;
3090 }
3091
3092 stimulus = wait_for_stimulus(props);
3093
3094 ast_debug(1, "Received stimulus %s on attended transfer %p\n", stimulus_strs[stimulus], props);
3095
3097
3098 props->state = state_properties[props->state].exit(props, stimulus);
3099
3100 ast_debug(1, "Told to enter state %s exit on attended transfer %p\n", state_properties[props->state].state_name, props);
3101 }
3102
3104
3105 if (callid) {
3107 }
3108
3109 return NULL;
3110}
static void attended_transfer_properties_shutdown(struct attended_transfer_properties *props)
Initiate shutdown of attended transfer properties.
attended_transfer_stimulus
Stimuli that can cause transfer state changes.
static const struct attended_transfer_state_properties state_properties[]
const char * stimulus_strs[]
String representations of the various stimuli.
static enum attended_transfer_stimulus wait_for_stimulus(struct attended_transfer_properties *props)
ast_callid ast_channel_callid(const struct ast_channel *chan)
#define ast_debug(level,...)
Log a DEBUG message.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:2308
unsigned int ast_callid
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
Definition: logger.c:2327
Collection of data related to an attended transfer attempt.
enum attended_transfer_state state
struct ast_channel * transferer
enum attended_transfer_state(* exit)(struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
enum attended_transfer_state_flags flags
int(* enter)(struct attended_transfer_properties *props)
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, ast_callid_threadassoc_add(), ast_callid_threadassoc_remove(), ast_channel_callid(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_log, attended_transfer_properties_shutdown(), attended_transfer_state_properties::enter, attended_transfer_state_properties::exit, attended_transfer_state_properties::flags, LOG_ERROR, NULL, attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, stimulus_strs, TRANSFER_STATE_FLAG_TERMINAL, attended_transfer_properties::transferer, and wait_for_stimulus().

Referenced by feature_attended_transfer().

◆ attended_transfer_properties_alloc()

static struct attended_transfer_properties * attended_transfer_properties_alloc ( struct ast_channel transferer,
const char *  context 
)
static

Allocate and initialize attended transfer properties.

Parameters
transfererThe channel performing the attended transfer
contextSuggestion for what context the transfer target extension can be found in
Return values
NULLFailure to allocate or initialize
non-NULLNewly allocated properties

Definition at line 1425 of file bridge_basic.c.

1427{
1428 struct attended_transfer_properties *props;
1429 char *tech;
1430 char *addr;
1431 char *serial;
1432 struct ast_features_xfer_config *xfer_cfg;
1433 struct ast_flags *transferer_features;
1434
1435 props = ao2_alloc(sizeof(*props), attended_transfer_properties_destructor);
1436 if (!props) {
1437 ast_log(LOG_ERROR, "Unable to create props - channel %s, context %s\n",
1438 ast_channel_name(transferer), context);
1439 return NULL;
1440 }
1441
1442 ast_cond_init(&props->cond, NULL);
1443
1444 if (ast_string_field_init(props, 64)) {
1445 ast_log(LOG_ERROR, "Unable to initialize prop fields - channel %s, context %s\n",
1446 ast_channel_name(transferer), context);
1447 ao2_ref(props, -1);
1448 return NULL;
1449 }
1450
1451 props->target_framehook_id = -1;
1452 props->transferer = ast_channel_ref(transferer);
1453
1456 if (!xfer_cfg) {
1457 ast_log(LOG_ERROR, "Unable to get transfer configuration from channel %s\n", ast_channel_name(props->transferer));
1459 ao2_ref(props, -1);
1460 return NULL;
1461 }
1462 transferer_features = ast_bridge_features_ds_get(props->transferer);
1463 if (transferer_features) {
1464 props->transferer_features = *transferer_features;
1465 }
1466 props->atxferdropcall = xfer_cfg->atxferdropcall;
1469 props->atxferloopdelay = xfer_cfg->atxferloopdelay;
1471 ast_string_field_set(props, xfersound, xfer_cfg->xfersound);
1472 ao2_ref(xfer_cfg, -1);
1473
1474 /*
1475 * Save the transferee's party information for any recall calls.
1476 * This is the only piece of information needed that gets overwritten
1477 * on the transferer channel by the inital call to the transfer target.
1478 */
1481
1482 tech = ast_strdupa(ast_channel_name(props->transferer));
1483 addr = strchr(tech, '/');
1484 if (!addr) {
1485 ast_log(LOG_ERROR, "Transferer channel name does not follow typical channel naming format (tech/address)\n");
1487 ao2_ref(props, -1);
1488 return NULL;
1489 }
1490 *addr++ = '\0';
1491 serial = strrchr(addr, '-');
1492 if (serial) {
1493 *serial = '\0';
1494 }
1495 ast_string_field_set(props, transferer_type, tech);
1496 ast_string_field_set(props, transferer_addr, addr);
1497
1499
1500 ast_debug(1, "Allocated attended transfer properties %p for transfer from %s\n",
1501 props, ast_channel_name(props->transferer));
1502 return props;
1503}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void attended_transfer_properties_destructor(void *obj)
static const char * get_transfer_context(struct ast_channel *transferer, const char *context)
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
Definition: channel.c:2031
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
struct ast_party_connected_line original_transferer_colp
struct ast_flags transferer_features

References ao2_alloc, ao2_ref, ast_bridge_features_ds_get(), ast_channel_connected(), ast_channel_lock, ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_cond_init, ast_debug, ast_get_chan_features_xfer_config(), ast_log, ast_party_connected_line_copy(), ast_strdupa, ast_string_field_init, ast_string_field_set, attended_transfer_properties_destructor(), ast_features_xfer_config::atxfercallbackretries, attended_transfer_properties::atxfercallbackretries, ast_features_xfer_config::atxferdropcall, attended_transfer_properties::atxferdropcall, ast_features_xfer_config::atxferloopdelay, attended_transfer_properties::atxferloopdelay, ast_features_xfer_config::atxfernoanswertimeout, attended_transfer_properties::atxfernoanswertimeout, attended_transfer_properties::cond, voicemailpwcheck::context, get_transfer_context(), LOG_ERROR, NULL, attended_transfer_properties::original_transferer_colp, attended_transfer_properties::target_framehook_id, attended_transfer_properties::transferer, attended_transfer_properties::transferer_features, and ast_features_xfer_config::xfersound.

Referenced by feature_attended_transfer().

◆ attended_transfer_properties_destructor()

static void attended_transfer_properties_destructor ( void *  obj)
static

Definition at line 1352 of file bridge_basic.c.

1353{
1354 struct attended_transfer_properties *props = obj;
1355
1356 ast_debug(1, "Destroy attended transfer properties %p\n", props);
1357
1358 ao2_cleanup(props->target_bridge);
1360 /* Use ast_channel_cleanup() instead of ast_channel_unref() for channels since they may be NULL */
1366 ast_cond_destroy(&props->cond);
1367}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
struct ast_bridge * transferee_bridge
struct ast_channel * recall_target
struct ast_bridge * target_bridge
struct ast_channel * transfer_target

References ao2_cleanup, ast_channel_cleanup, ast_cond_destroy, ast_debug, ast_party_connected_line_free(), ast_string_field_free_memory, attended_transfer_properties::cond, attended_transfer_properties::original_transferer_colp, attended_transfer_properties::recall_target, attended_transfer_properties::target_bridge, attended_transfer_properties::transfer_target, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

Referenced by attended_transfer_properties_alloc().

◆ attended_transfer_properties_shutdown()

static void attended_transfer_properties_shutdown ( struct attended_transfer_properties props)
static

Initiate shutdown of attended transfer properties.

Calling this indicates that the attended transfer properties are no longer needed because the transfer operation has concluded.

Definition at line 1524 of file bridge_basic.c.

1525{
1526 ast_debug(1, "Shutting down attended transfer %p\n", props);
1527
1528 if (props->transferee_bridge) {
1532 }
1533
1534 if (props->target_bridge) {
1536 props->target_bridge = NULL;
1537 }
1538
1539 if (props->transferer) {
1541 }
1542
1543 clear_stimulus_queue(props);
1544
1545 ao2_cleanup(props);
1546}
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request)
Adjust the bridge merge inhibit request count.
Definition: bridge.c:3000
static void bridge_basic_change_personality(struct ast_bridge *bridge, enum bridge_basic_personality_type type, void *user_data)
Change basic bridge personality.
static void clear_stimulus_queue(struct attended_transfer_properties *props)
Free backlog of stimuli in the queue.
void ast_channel_remove_bridge_role(struct ast_channel *chan, const char *role_name)
Removes a bridge role from a channel.
Definition: bridge_roles.c:332

References ao2_cleanup, ast_bridge_destroy(), ast_bridge_merge_inhibit(), ast_channel_remove_bridge_role(), ast_debug, AST_TRANSFERER_ROLE_NAME, bridge_basic_change_personality(), BRIDGE_BASIC_PERSONALITY_NORMAL, clear_stimulus_queue(), NULL, attended_transfer_properties::target_bridge, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

Referenced by attended_transfer_monitor_thread(), and feature_attended_transfer().

◆ atxfer_abort()

static int atxfer_abort ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

DTMF hook when transferer presses abort sequence.

Sends a stimulus to the attended transfer monitor thread that the abort sequence has been pressed

Definition at line 2755 of file bridge_basic.c.

2756{
2757 struct attended_transfer_properties *props = hook_pvt;
2758
2759 ast_debug(1, "Transferer on attended transfer %p pressed abort sequence\n", props);
2761 return 0;
2762}
static void stimulate_attended_transfer(struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)

References ast_debug, stimulate_attended_transfer(), and STIMULUS_DTMF_ATXFER_ABORT.

Referenced by add_transferer_role(), and bridge_personality_atxfer_push().

◆ atxfer_complete()

static int atxfer_complete ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

DTMF hook when transferer presses complete sequence.

Sends a stimulus to the attended transfer monitor thread that the complete sequence has been pressed

Definition at line 2769 of file bridge_basic.c.

2770{
2771 struct attended_transfer_properties *props = hook_pvt;
2772
2773 ast_debug(1, "Transferer on attended transfer %p pressed complete sequence\n", props);
2775 return 0;
2776}

References ast_debug, stimulate_attended_transfer(), and STIMULUS_DTMF_ATXFER_COMPLETE.

Referenced by add_transferer_role(), and bridge_personality_atxfer_push().

◆ atxfer_swap()

static int atxfer_swap ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

DTMF hook when transferer presses swap sequence.

Sends a stimulus to the attended transfer monitor thread that the swap sequence has been pressed

Definition at line 2797 of file bridge_basic.c.

2798{
2799 struct attended_transfer_properties *props = hook_pvt;
2800
2801 ast_debug(1, "Transferer on attended transfer %p pressed swap sequence\n", props);
2803 return 0;
2804}

References ast_debug, stimulate_attended_transfer(), and STIMULUS_DTMF_ATXFER_SWAP.

Referenced by add_transferer_role(), and bridge_personality_atxfer_push().

◆ atxfer_threeway()

static int atxfer_threeway ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

DTMF hook when transferer presses threeway sequence.

Sends a stimulus to the attended transfer monitor thread that the threeway sequence has been pressed

Definition at line 2783 of file bridge_basic.c.

2784{
2785 struct attended_transfer_properties *props = hook_pvt;
2786
2787 ast_debug(1, "Transferer on attended transfer %p pressed threeway sequence\n", props);
2789 return 0;
2790}

References ast_debug, stimulate_attended_transfer(), and STIMULUS_DTMF_ATXFER_THREEWAY.

Referenced by add_transferer_role(), and bridge_personality_atxfer_push().

◆ atxfer_transferer_hangup()

static int atxfer_transferer_hangup ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Hangup hook for transferer channel.

Sends a stimulus to the attended transfer monitor thread that the transferer has hung up.

Definition at line 2811 of file bridge_basic.c.

2812{
2813 struct attended_transfer_properties *props = hook_pvt;
2814
2815 ast_debug(1, "Transferer on attended transfer %p hung up\n", props);
2817 return 0;
2818}

References ast_debug, stimulate_attended_transfer(), and STIMULUS_TRANSFERER_HANGUP.

Referenced by bridge_personality_atxfer_push().

◆ basic_hangup_hook()

static int basic_hangup_hook ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Definition at line 290 of file bridge_basic.c.

291{
292 int bridge_count = 0;
293 struct ast_bridge_channel *iter;
294
295 ast_bridge_channel_lock_bridge(bridge_channel);
296 AST_LIST_TRAVERSE(&bridge_channel->bridge->channels, iter, entry) {
297 if (iter != bridge_channel && iter->state == BRIDGE_CHANNEL_STATE_WAIT) {
298 ++bridge_count;
299 }
300 }
301 if (2 <= bridge_count) {
302 /* Just allow this channel to leave the multi-party bridge. */
303 ast_bridge_channel_leave_bridge(bridge_channel,
305 }
306 ast_bridge_unlock(bridge_channel->bridge);
307 return 0;
308}
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
@ BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE
@ BRIDGE_CHANNEL_STATE_WAIT
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
Structure that contains information regarding a channel in a bridge.
struct ast_bridge * bridge
Bridge this channel is participating in.
enum bridge_channel_state state
struct ast_bridge_channels_list channels
Definition: bridge.h:363
Definition: search.h:40

References ast_bridge_channel_leave_bridge(), ast_bridge_channel_lock_bridge(), ast_bridge_unlock, AST_LIST_TRAVERSE, ast_bridge_channel::bridge, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, ast_bridge::channels, and ast_bridge_channel::state.

Referenced by add_normal_hooks().

◆ blind_transfer_cb()

static void blind_transfer_cb ( struct ast_channel new_channel,
struct transfer_channel_data user_data_wrapper,
enum ast_transfer_type  transfer_type 
)
static

Definition at line 3499 of file bridge_basic.c.

3501{
3502 struct ast_channel *transferer_channel = user_data_wrapper->data;
3503
3504 if (transfer_type == AST_BRIDGE_TRANSFER_MULTI_PARTY) {
3505 copy_caller_data(new_channel, transferer_channel);
3506 }
3507}
@ AST_BRIDGE_TRANSFER_MULTI_PARTY
Definition: bridge.h:1113
static void copy_caller_data(struct ast_channel *dest, struct ast_channel *caller)
Main Channel structure associated with a channel.

References AST_BRIDGE_TRANSFER_MULTI_PARTY, copy_caller_data(), and transfer_channel_data::data.

Referenced by feature_blind_transfer().

◆ blond_enter()

static int blond_enter ( struct attended_transfer_properties props)
static

Definition at line 2338 of file bridge_basic.c.

2339{
2340 struct ast_channel *transferee_channel;
2341 struct ast_channel *target_channel;
2342
2344 &transferee_channel, &target_channel);
2345 bridge_merge(props->transferee_bridge, props->target_bridge, &props->transferer, 1);
2346 ringing(props->transfer_target);
2347 publish_transfer_success(props, transferee_channel, target_channel);
2348
2349 ast_channel_cleanup(transferee_channel);
2350 ast_channel_cleanup(target_channel);
2351 return 0;
2352}
static void ringing(struct ast_channel *chan)
Helper method to send a ringing indication to a channel in a bridge.
static void get_transfer_parties(struct ast_channel *transferer, struct ast_bridge *transferee_bridge, struct ast_bridge *target_bridge, struct ast_channel **transferee, struct ast_channel **transfer_target)
determine transferee and transfer target for an attended transfer
static void publish_transfer_success(struct attended_transfer_properties *props, struct ast_channel *transferee_channel, struct ast_channel *target_channel)
Send a stasis publication for a successful attended transfer.
static void bridge_merge(struct ast_bridge *dest, struct ast_bridge *src, struct ast_channel **kick_channels, unsigned int num_channels)
Wrapper for bridge_do_merge.

References ast_channel_cleanup, bridge_merge(), get_transfer_parties(), publish_transfer_success(), ringing(), attended_transfer_properties::target_bridge, attended_transfer_properties::transfer_target, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

Referenced by blond_nonfinal_enter().

◆ blond_nonfinal_enter()

static int blond_nonfinal_enter ( struct attended_transfer_properties props)
static

Definition at line 2354 of file bridge_basic.c.

2355{
2356 int res;
2358 /* move the transfer target to the recall target along with its reference */
2360 res = blond_enter(props);
2362 return res;
2363}
static int blond_enter(struct attended_transfer_properties *props)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
enum attended_transfer_superstate superstate

References ast_channel_ref, ast_channel_unref, blond_enter(), attended_transfer_properties::recall_target, attended_transfer_properties::superstate, SUPERSTATE_RECALL, and attended_transfer_properties::transfer_target.

◆ blond_nonfinal_exit()

static enum attended_transfer_state blond_nonfinal_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 2365 of file bridge_basic.c.

2367{
2368 switch (stimulus) {
2370 return TRANSFER_FAIL;
2372 return TRANSFER_RESUME;
2373 case STIMULUS_TIMEOUT:
2375 /* It is possible before we hung them up that they queued up a recall target answer
2376 * so we remove it if present as it should not exist.
2377 */
2381 return TRANSFER_RECALLING;
2382 case STIMULUS_NONE:
2390 default:
2391 ast_log(LOG_WARNING, "Unexpected stimulus '%s' received in attended transfer state '%s'\n",
2392 stimulus_strs[stimulus], state_properties[props->state].state_name);
2393 return props->state;
2394 }
2395}
static void remove_attended_transfer_stimulus(struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1148
#define LOG_WARNING

References ast_channel_unref, ast_log, ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, LOG_WARNING, attended_transfer_properties::recall_target, remove_attended_transfer_stimulus(), attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, STIMULUS_DTMF_ATXFER_ABORT, STIMULUS_DTMF_ATXFER_COMPLETE, STIMULUS_DTMF_ATXFER_SWAP, STIMULUS_DTMF_ATXFER_THREEWAY, STIMULUS_NONE, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_RECALL_TARGET_HANGUP, stimulus_strs, STIMULUS_TIMEOUT, STIMULUS_TRANSFER_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, STIMULUS_TRANSFERER_HANGUP, TRANSFER_FAIL, TRANSFER_RECALLING, and TRANSFER_RESUME.

◆ bridge_basic_change_personality()

static void bridge_basic_change_personality ( struct ast_bridge bridge,
enum bridge_basic_personality_type  type,
void *  user_data 
)
static

Change basic bridge personality.

Changing personalities allows for the bridge to remain in use but have properties such as its v_table and its flags change.

Parameters
bridgeThe bridge
typeThe personality to change the bridge to
user_dataPrivate data to attach to the personality.

Definition at line 3568 of file bridge_basic.c.

3570{
3571 struct bridge_basic_personality *personality = bridge->personality;
3573
3575
3576 ao2_cleanup(personality->details[personality->current].pvt);
3577 personality->details[personality->current].pvt = NULL;
3579
3580 personality->current = type;
3581 if (user_data) {
3582 ao2_ref(user_data, +1);
3583 }
3584 personality->details[personality->current].pvt = user_data;
3585 ast_set_flag(&bridge->feature_flags, personality->details[personality->current].bridge_flags);
3586 if (personality->details[personality->current].on_personality_change) {
3587 personality->details[personality->current].on_personality_change(bridge);
3588 }
3589}
static void remove_hooks_on_personality_change(struct ast_bridge *bridge)
Remove appropriate hooks when basic bridge personality changes.
Definition: bridge_basic.c:719
static const char type[]
Definition: chan_ooh323.c:109
void(* on_personality_change)(struct ast_bridge *bridge)
Definition: bridge_basic.c:321
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define AST_FLAGS_ALL
Definition: utils.h:196

References ao2_cleanup, ao2_ref, ast_bridge_lock, ast_bridge_unlock, ast_clear_flag, AST_FLAGS_ALL, ast_set_flag, personality_details::bridge_flags, bridge_basic_personality::current, bridge_basic_personality::details, ast_bridge::feature_flags, lock, NULL, personality_details::on_personality_change, ast_bridge::personality, personality_details::pvt, remove_hooks_on_personality_change(), SCOPED_LOCK, and type.

Referenced by attended_transfer_properties_shutdown(), consulting_exit(), and feature_attended_transfer().

◆ bridge_basic_destroy()

static void bridge_basic_destroy ( struct ast_bridge self)
static

Definition at line 702 of file bridge_basic.c.

703{
704 struct bridge_basic_personality *personality = self->personality;
705
706 ao2_cleanup(personality);
707
709}

References ao2_cleanup, ast_bridge_base_v_table, ast_bridge_methods::destroy, and ast_bridge::personality.

Referenced by ast_bridging_init_basic().

◆ bridge_basic_personality_alloc()

static struct ast_bridge * bridge_basic_personality_alloc ( struct ast_bridge bridge)
static

Definition at line 3632 of file bridge_basic.c.

3633{
3634 struct bridge_basic_personality *personality;
3635 int i;
3636
3637 if (!bridge) {
3638 return NULL;
3639 }
3640
3641 personality = ao2_alloc(sizeof(*personality), personality_destructor);
3642 if (!personality) {
3643 ao2_ref(bridge, -1);
3644 return NULL;
3645 }
3646 for (i = 0; i < BRIDGE_BASIC_PERSONALITY_END; ++i) {
3647 init_details(&personality->details[i], i);
3648 }
3650 bridge->personality = personality;
3651
3652 return bridge;
3653}
static void init_details(struct personality_details *details, enum bridge_basic_personality_type type)
static void personality_destructor(void *obj)

References ao2_alloc, ao2_ref, BRIDGE_BASIC_PERSONALITY_END, BRIDGE_BASIC_PERSONALITY_NORMAL, bridge_basic_personality::current, bridge_basic_personality::details, init_details(), NULL, ast_bridge::personality, and personality_destructor().

Referenced by ast_bridge_basic_new().

◆ bridge_basic_pull()

static void bridge_basic_pull ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 687 of file bridge_basic.c.

688{
689 struct bridge_basic_personality *personality = self->personality;
690
691 ast_assert(personality != NULL);
692
693 if (personality->details[personality->current].v_table->pull) {
694 personality->details[personality->current].v_table->pull(self, bridge_channel);
695 }
696
698
699 ast_bridge_base_v_table.pull(self, bridge_channel);
700}
void ast_bridge_channel_update_accountcodes(struct ast_bridge_channel *joining, struct ast_bridge_channel *leaving)
struct ast_bridge_methods * v_table
Definition: bridge_basic.c:315

References ast_assert, ast_bridge_base_v_table, ast_bridge_channel_update_accountcodes(), bridge_basic_personality::current, bridge_basic_personality::details, NULL, ast_bridge::personality, ast_bridge_methods::pull, and personality_details::v_table.

Referenced by ast_bridging_init_basic().

◆ bridge_basic_push()

static int bridge_basic_push ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel,
struct ast_bridge_channel swap 
)
static

Definition at line 670 of file bridge_basic.c.

671{
672 struct bridge_basic_personality *personality = self->personality;
673
674 ast_assert(personality != NULL);
675
676 if (personality->details[personality->current].v_table->push
677 && personality->details[personality->current].v_table->push(self, bridge_channel, swap)) {
678 return -1;
679 }
680
681 ast_bridge_channel_update_linkedids(bridge_channel, swap);
682 ast_bridge_channel_update_accountcodes(bridge_channel, swap);
683
684 return ast_bridge_base_v_table.push(self, bridge_channel, swap);
685}
void ast_bridge_channel_update_linkedids(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)

References ast_assert, ast_bridge_base_v_table, ast_bridge_channel_update_accountcodes(), ast_bridge_channel_update_linkedids(), bridge_basic_personality::current, bridge_basic_personality::details, NULL, ast_bridge::personality, ast_bridge_methods::push, and personality_details::v_table.

Referenced by ast_bridging_init_basic().

◆ bridge_basic_setup_features()

static int bridge_basic_setup_features ( struct ast_bridge_channel bridge_channel)
static

Definition at line 630 of file bridge_basic.c.

631{
632 int res = 0;
633
634 res |= setup_bridge_features_builtin(bridge_channel->features, bridge_channel->chan);
635 res |= setup_bridge_features_dynamic(bridge_channel->features, bridge_channel->chan);
636
637 return res;
638}
static int setup_bridge_features_dynamic(struct ast_bridge_features *features, struct ast_channel *chan)
Definition: bridge_basic.c:604
static int setup_bridge_features_builtin(struct ast_bridge_features *features, struct ast_channel *chan)
Definition: bridge_basic.c:400
struct ast_channel * chan

References ast_bridge_channel::chan, ast_bridge_channel::features, setup_bridge_features_builtin(), and setup_bridge_features_dynamic().

Referenced by add_normal_hooks().

◆ bridge_features_ds_set_full()

static int bridge_features_ds_set_full ( struct ast_channel chan,
struct ast_flags flags,
int  replace 
)
static

Definition at line 224 of file bridge_basic.c.

225{
226 struct ast_datastore *datastore;
227 struct ast_flags *ds_flags;
228
230 if (datastore) {
231 ds_flags = datastore->data;
232 if (replace) {
233 *ds_flags = *flags;
234 } else {
235 flags->flags = flags->flags | ds_flags->flags;
236 *ds_flags = *flags;
237 }
238 return 0;
239 }
240
242 if (!datastore) {
243 return -1;
244 }
245
246 ds_flags = ast_malloc(sizeof(*ds_flags));
247 if (!ds_flags) {
248 ast_datastore_free(datastore);
249 return -1;
250 }
251
252 *ds_flags = *flags;
253 datastore->data = ds_flags;
254 ast_channel_datastore_add(chan, datastore);
255 return 0;
256}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:888

References ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), ast_malloc, ast_datastore::data, dtmf_features_info, ast_flags::flags, NULL, and replace().

Referenced by ast_bridge_features_ds_append(), and ast_bridge_features_ds_set().

◆ bridge_hold()

static void bridge_hold ( struct ast_bridge bridge)
static

Helper method to send a hold frame to all channels in a bridge.

Definition at line 1860 of file bridge_basic.c.

1861{
1862 struct ast_frame hold = {
1863 .frametype = AST_FRAME_CONTROL,
1864 .subclass.integer = AST_CONTROL_HOLD,
1865 };
1866
1868}
int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Queue the given frame to everyone else.
static void hold(struct ast_channel *chan)
Helper method to place a channel in a bridge on hold.
@ AST_FRAME_CONTROL
@ AST_CONTROL_HOLD
Data structure associated with a single frame of data.

References ast_bridge_queue_everyone_else(), AST_CONTROL_HOLD, AST_FRAME_CONTROL, hold(), and NULL.

Referenced by wait_to_recall_enter(), and wait_to_retransfer_enter().

◆ bridge_merge()

static void bridge_merge ( struct ast_bridge dest,
struct ast_bridge src,
struct ast_channel **  kick_channels,
unsigned int  num_channels 
)
static

Wrapper for bridge_do_merge.

Definition at line 1913 of file bridge_basic.c.

1914{
1915 struct ast_bridge_channel **kick_bridge_channels = num_channels ?
1916 ast_alloca(num_channels * sizeof(*kick_bridge_channels)) : NULL;
1917 int i;
1918 int num_bridge_channels = 0;
1919
1920 ast_bridge_lock_both(dest, src);
1921
1922 for (i = 0; i < num_channels; ++i) {
1923 struct ast_bridge_channel *kick_bridge_channel;
1924
1925 kick_bridge_channel = bridge_find_channel(src, kick_channels[i]);
1926 if (!kick_bridge_channel) {
1927 kick_bridge_channel = bridge_find_channel(dest, kick_channels[i]);
1928 }
1929
1930 /* It's possible (and fine) for the bridge channel to be NULL at this point if the
1931 * channel has hung up already. If that happens, we can just remove it from the list
1932 * of bridge channels to kick from the bridge
1933 */
1934 if (!kick_bridge_channel) {
1935 continue;
1936 }
1937
1938 kick_bridge_channels[num_bridge_channels++] = kick_bridge_channel;
1939 }
1940
1941 bridge_do_merge(dest, src, kick_bridge_channels, num_bridge_channels, 0);
1942 ast_bridge_unlock(dest);
1943 ast_bridge_unlock(src);
1944}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:488
void bridge_do_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, unsigned int num_kick, unsigned int optimized)
Definition: bridge.c:2048
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1429

References ast_alloca, ast_bridge_lock_both, ast_bridge_unlock, bridge_do_merge(), bridge_find_channel(), and NULL.

Referenced by blond_enter(), complete_enter(), and threeway_enter().

◆ bridge_move()

static void bridge_move ( struct ast_bridge dest,
struct ast_bridge src,
struct ast_channel channel,
struct ast_channel swap 
)
static

Wrapper for bridge_do_move.

Definition at line 1886 of file bridge_basic.c.

1887{
1888 struct ast_bridge_channel *bridge_channel;
1889
1890 ast_bridge_lock_both(src, dest);
1891
1892 ast_channel_lock(channel);
1893 bridge_channel = ast_channel_get_bridge_channel(channel);
1894 ast_channel_unlock(channel);
1895
1896 if (bridge_channel) {
1897 ao2_lock(bridge_channel);
1898 bridge_channel->swap = swap;
1899 ao2_unlock(bridge_channel);
1900
1901 bridge_do_move(dest, bridge_channel, 1, 0);
1902 }
1903
1904 ast_bridge_unlock(dest);
1905 ast_bridge_unlock(src);
1906
1907 ao2_cleanup(bridge_channel);
1908}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition: bridge.c:2314
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10582
struct ast_channel * swap

References ao2_cleanup, ao2_lock, ao2_unlock, ast_bridge_lock_both, ast_bridge_unlock, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, bridge_do_move(), and ast_bridge_channel::swap.

Referenced by calling_target_enter(), consulting_exit(), double_checking_exit(), hesitant_enter(), and rebridge_enter().

◆ bridge_personality_atxfer_pull()

static void bridge_personality_atxfer_pull ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 2994 of file bridge_basic.c.

2995{
2996 struct bridge_basic_personality *personality = self->personality;
2997 struct attended_transfer_properties *props = personality->details[personality->current].pvt;
2998
2999 switch (props->superstate) {
3001 transfer_pull(self, bridge_channel, props);
3002 break;
3003 case SUPERSTATE_RECALL:
3004 recall_pull(self, bridge_channel, props);
3005 break;
3006 }
3007}
static void recall_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct attended_transfer_properties *props)
static void transfer_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct attended_transfer_properties *props)

References bridge_basic_personality::current, bridge_basic_personality::details, ast_bridge::personality, personality_details::pvt, recall_pull(), attended_transfer_properties::superstate, SUPERSTATE_RECALL, SUPERSTATE_TRANSFER, and transfer_pull().

Referenced by ast_bridging_init_basic().

◆ bridge_personality_atxfer_push()

static int bridge_personality_atxfer_push ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel,
struct ast_bridge_channel swap 
)
static

Definition at line 2869 of file bridge_basic.c.

2870{
2871 const char *abort_dtmf;
2872 const char *complete_dtmf;
2873 const char *threeway_dtmf;
2874 const char *swap_dtmf;
2875 struct bridge_basic_personality *personality = self->personality;
2876
2877 if (!ast_channel_has_role(bridge_channel->chan, AST_TRANSFERER_ROLE_NAME)) {
2878 return 0;
2879 }
2880
2881 abort_dtmf = ast_channel_get_role_option(bridge_channel->chan, AST_TRANSFERER_ROLE_NAME, "abort");
2882 complete_dtmf = ast_channel_get_role_option(bridge_channel->chan, AST_TRANSFERER_ROLE_NAME, "complete");
2883 threeway_dtmf = ast_channel_get_role_option(bridge_channel->chan, AST_TRANSFERER_ROLE_NAME, "threeway");
2884 swap_dtmf = ast_channel_get_role_option(bridge_channel->chan, AST_TRANSFERER_ROLE_NAME, "swap");
2885
2886 if (!ast_strlen_zero(abort_dtmf) && ast_bridge_dtmf_hook(bridge_channel->features,
2887 abort_dtmf, atxfer_abort, personality->details[personality->current].pvt, NULL,
2889 return -1;
2890 }
2891 if (!ast_strlen_zero(complete_dtmf) && ast_bridge_dtmf_hook(bridge_channel->features,
2892 complete_dtmf, atxfer_complete, personality->details[personality->current].pvt, NULL,
2894 return -1;
2895 }
2896 if (!ast_strlen_zero(threeway_dtmf) && ast_bridge_dtmf_hook(bridge_channel->features,
2897 threeway_dtmf, atxfer_threeway, personality->details[personality->current].pvt, NULL,
2899 return -1;
2900 }
2901 if (!ast_strlen_zero(swap_dtmf) && ast_bridge_dtmf_hook(bridge_channel->features,
2902 swap_dtmf, atxfer_swap, personality->details[personality->current].pvt, NULL,
2904 return -1;
2905 }
2907 personality->details[personality->current].pvt, NULL,
2909 return -1;
2910 }
2911
2912 return 0;
2913}
static int atxfer_transferer_hangup(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hangup hook for transferer channel.
@ AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE
int ast_bridge_dtmf_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a DTMF hook to a bridge features structure.
Definition: bridge.c:3182
const char * ast_channel_get_role_option(struct ast_channel *channel, const char *role_name, const char *option)
Retrieve the value of a requested role option from a channel.
Definition: bridge_roles.c:399
int ast_channel_has_role(struct ast_channel *channel, const char *role_name)
Check if a role exists on a channel.
Definition: bridge_roles.c:394
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_bridge_dtmf_hook(), ast_bridge_hangup_hook(), AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE, AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_channel_get_role_option(), ast_channel_has_role(), ast_strlen_zero(), AST_TRANSFERER_ROLE_NAME, atxfer_abort(), atxfer_complete(), atxfer_swap(), atxfer_threeway(), atxfer_transferer_hangup(), ast_bridge_channel::chan, bridge_basic_personality::current, bridge_basic_personality::details, ast_bridge_channel::features, NULL, ast_bridge::personality, and personality_details::pvt.

Referenced by ast_bridging_init_basic().

◆ bridge_personality_normal_push()

static int bridge_personality_normal_push ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel,
struct ast_bridge_channel swap 
)
static

Definition at line 661 of file bridge_basic.c.

662{
663 if (add_normal_hooks(self, bridge_channel)) {
664 return -1;
665 }
666
667 return 0;
668}
static int add_normal_hooks(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge_basic.c:640

References add_normal_hooks().

Referenced by ast_bridging_init_basic().

◆ bridge_ringing()

static void bridge_ringing ( struct ast_bridge bridge)
static

Helper method to send a ringing indication to all channels in a bridge.

Definition at line 1847 of file bridge_basic.c.

1848{
1849 struct ast_frame ringing = {
1850 .frametype = AST_FRAME_CONTROL,
1851 .subclass.integer = AST_CONTROL_RINGING,
1852 };
1853
1855}
@ AST_CONTROL_RINGING

References ast_bridge_queue_everyone_else(), AST_CONTROL_RINGING, AST_FRAME_CONTROL, NULL, and ringing().

Referenced by recalling_enter().

◆ bridge_unhold()

static void bridge_unhold ( struct ast_bridge bridge)
static

Helper method to send an unhold frame to all channels in a bridge.

Definition at line 1873 of file bridge_basic.c.

1874{
1875 struct ast_frame unhold = {
1876 .frametype = AST_FRAME_CONTROL,
1877 .subclass.integer = AST_CONTROL_UNHOLD,
1878 };
1879
1881}
static void unhold(struct ast_channel *chan)
Helper method to take a channel in a bridge off hold.
@ AST_CONTROL_UNHOLD

References ast_bridge_queue_everyone_else(), AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, NULL, and unhold().

Referenced by calling_target_exit(), consulting_exit(), double_checking_exit(), wait_to_recall_exit(), and wait_to_retransfer_exit().

◆ build_dtmf_features()

static int build_dtmf_features ( struct ast_flags flags,
const char *  features 
)
static

Definition at line 162 of file bridge_basic.c.

163{
164 const char *feature;
165
166 char missing_features[strlen(features) + 1];
167 size_t number_of_missing_features = 0;
168
169 for (feature = features; *feature; feature++) {
170 if (!isupper(*feature)) {
171 ast_log(LOG_ERROR, "Features string '%s' rejected because it contains non-uppercase feature.\n", features);
172 return -1;
173 }
174
175 if (set_feature_flag_from_char(flags, *feature)) {
176 missing_features[number_of_missing_features++] = *feature;
177 }
178 }
179
180 missing_features[number_of_missing_features] = '\0';
181
182 if (number_of_missing_features) {
183 ast_log(LOG_WARNING, "Features '%s' from features string '%s' can not be applied.\n", missing_features, features);
184 }
185
186 return 0;
187}
static int set_feature_flag_from_char(struct ast_flags *feature_flags, char feature)
Definition: bridge_basic.c:98

References ast_log, LOG_ERROR, LOG_WARNING, and set_feature_flag_from_char().

Referenced by ast_bridge_features_ds_set_string().

◆ builtin_feature_get_exten()

static int builtin_feature_get_exten ( struct ast_channel chan,
const char *  feature_name,
char *  buf,
size_t  len 
)
static

Definition at line 346 of file bridge_basic.c.

347{
349
350 return ast_get_builtin_feature(chan, feature_name, buf, len);
351}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
Get the DTMF code for a builtin feature.

References ast_get_builtin_feature(), buf, len(), lock, and SCOPED_CHANNELLOCK.

Referenced by builtin_features_helper().

◆ builtin_features_helper()

static int builtin_features_helper ( struct ast_bridge_features features,
struct ast_channel chan,
struct ast_flags flags,
unsigned int  feature_flag,
const char *  feature_name,
enum ast_bridge_builtin_feature  feature_bridge 
)
static

Definition at line 368 of file bridge_basic.c.

370{
371 char dtmf[AST_FEATURE_MAX_LEN];
372 int res;
373
374 res = 0;
375 if (ast_test_flag(flags, feature_flag)
376 && !builtin_feature_get_exten(chan, feature_name, dtmf, sizeof(dtmf))
377 && !ast_strlen_zero(dtmf)) {
378 res = ast_bridge_features_enable(features, feature_bridge, dtmf, NULL, NULL,
380 if (res) {
381 ast_log(LOG_ERROR, "Channel %s: Requested DTMF feature %s not available.\n",
382 ast_channel_name(chan), feature_name);
383 }
384 }
385
386 return res;
387}
static int builtin_feature_get_exten(struct ast_channel *chan, const char *feature_name, char *buf, size_t len)
Definition: bridge_basic.c:346
int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Enable a built in feature on a bridge features structure.
Definition: bridge.c:3365
#define AST_FEATURE_MAX_LEN
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_bridge_features_enable(), AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE, AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_channel_name(), AST_FEATURE_MAX_LEN, ast_log, ast_strlen_zero(), ast_test_flag, builtin_feature_get_exten(), LOG_ERROR, and NULL.

Referenced by setup_bridge_features_builtin().

◆ calling_target_enter()

static int calling_target_enter ( struct attended_transfer_properties props)
static

Definition at line 2116 of file bridge_basic.c.

2117{
2119 return 0;
2120}
static void bridge_move(struct ast_bridge *dest, struct ast_bridge *src, struct ast_channel *channel, struct ast_channel *swap)
Wrapper for bridge_do_move.

References bridge_move(), NULL, attended_transfer_properties::target_bridge, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

◆ calling_target_exit()

static enum attended_transfer_state calling_target_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 2122 of file bridge_basic.c.

2124{
2125 switch (stimulus) {
2127 play_failsound(props->transferer);
2128 publish_transfer_fail(props);
2129 return TRANSFER_FAIL;
2135 return TRANSFER_CONSULTING;
2137 case STIMULUS_TIMEOUT:
2139 play_failsound(props->transferer);
2140 return TRANSFER_REBRIDGE;
2143 return TRANSFER_THREEWAY;
2145 return TRANSFER_HESITANT;
2146 case STIMULUS_NONE:
2149 default:
2150 ast_log(LOG_WARNING, "Unexpected stimulus '%s' received in attended transfer state '%s'\n",
2151 stimulus_strs[stimulus], state_properties[props->state].state_name);
2152 return props->state;
2153 }
2154}
static void play_failsound(struct ast_channel *chan)
Helper method to play a fail sound on a channel in a bridge.
static void publish_transfer_fail(struct attended_transfer_properties *props)
Send a stasis publication for a failed attended transfer.
static void bridge_unhold(struct ast_bridge *bridge)
Helper method to send an unhold frame to all channels in a bridge.

References ast_log, attended_transfer_properties::atxferdropcall, bridge_unhold(), LOG_WARNING, play_failsound(), publish_transfer_fail(), attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, STIMULUS_DTMF_ATXFER_ABORT, STIMULUS_DTMF_ATXFER_COMPLETE, STIMULUS_DTMF_ATXFER_SWAP, STIMULUS_DTMF_ATXFER_THREEWAY, STIMULUS_NONE, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_RECALL_TARGET_HANGUP, stimulus_strs, STIMULUS_TIMEOUT, STIMULUS_TRANSFER_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, STIMULUS_TRANSFERER_HANGUP, TRANSFER_BLOND, TRANSFER_BLOND_NONFINAL, TRANSFER_CONSULTING, TRANSFER_FAIL, TRANSFER_HESITANT, TRANSFER_REBRIDGE, TRANSFER_THREEWAY, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

◆ clear_stimulus_queue()

static void clear_stimulus_queue ( struct attended_transfer_properties props)
static

Free backlog of stimuli in the queue.

Definition at line 1508 of file bridge_basic.c.

1509{
1510 struct stimulus_list *list;
1511 SCOPED_AO2LOCK(lock, props);
1512
1513 while ((list = AST_LIST_REMOVE_HEAD(&props->stimulus_queue, next))) {
1514 ast_free(list);
1515 }
1516}
#define ast_free(a)
Definition: astmm.h:180
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:604
struct attended_transfer_properties::@313 stimulus_queue
struct stimulus_list * next

References ast_free, AST_LIST_REMOVE_HEAD, lock, stimulus_list::next, SCOPED_AO2LOCK, and attended_transfer_properties::stimulus_queue.

Referenced by attended_transfer_properties_shutdown().

◆ common_recall_channel_setup()

static void common_recall_channel_setup ( struct ast_channel recall,
struct ast_channel transferer 
)
static

Definition at line 2447 of file bridge_basic.c.

2448{
2449 ast_callid callid;
2450
2452 if (callid) {
2453 ast_channel_callid_set(recall, callid);
2454 }
2455
2456 ast_channel_inherit_variables(transferer, recall);
2457 ast_channel_datastore_inherit(transferer, recall);
2458
2459 /*
2460 * Stage a snapshot to ensure that a snapshot is always done
2461 * on the recall channel so earlier COLP and CLID setup will
2462 * get published.
2463 */
2467}
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1479
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2368
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6434
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
Definition: channel.c:6771
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
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.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2286

References ast_channel_callid_set(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_REPLACEMENT, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_read_threadstorage_callid(), and attended_transfer_properties::transferer.

Referenced by recalling_enter(), and retransfer_enter().

◆ complete_enter()

static int complete_enter ( struct attended_transfer_properties props)
static

Definition at line 2322 of file bridge_basic.c.

2323{
2324 struct ast_channel *transferee_channel;
2325 struct ast_channel *target_channel;
2326
2328 &transferee_channel, &target_channel);
2329 bridge_merge(props->transferee_bridge, props->target_bridge, &props->transferer, 1);
2330 play_sound(props->transfer_target, props->xfersound);
2331 publish_transfer_success(props, transferee_channel, target_channel);
2332
2333 ast_channel_cleanup(transferee_channel);
2334 ast_channel_cleanup(target_channel);
2335 return 0;
2336}
static void play_sound(struct ast_channel *chan, const char *sound)
Helper method to play a sound on a channel in a bridge.
const ast_string_field xfersound

References ast_channel_cleanup, bridge_merge(), get_transfer_parties(), play_sound(), publish_transfer_success(), attended_transfer_properties::target_bridge, attended_transfer_properties::transfer_target, attended_transfer_properties::transferee_bridge, attended_transfer_properties::transferer, and attended_transfer_properties::xfersound.

◆ consulting_enter()

static int consulting_enter ( struct attended_transfer_properties props)
static

Definition at line 2225 of file bridge_basic.c.

2226{
2227 return 0;
2228}

◆ consulting_exit()

static enum attended_transfer_state consulting_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 2230 of file bridge_basic.c.

2232{
2233 switch (stimulus) {
2235 /* This is a one-of-a-kind event. The transferer and transfer target are talking in
2236 * one bridge, and the transferee has hung up in a separate bridge. In this case, we
2237 * will change the personality of the transfer target bridge back to normal, and play
2238 * a sound to the transferer to indicate the transferee is gone.
2239 */
2241 play_failsound(props->transferer);
2243 /* These next two lines are here to ensure that our reference to the target bridge
2244 * is cleaned up properly and that the target bridge is not destroyed when the
2245 * monitor thread exits
2246 */
2247 ao2_ref(props->target_bridge, -1);
2248 props->target_bridge = NULL;
2249 return TRANSFER_FAIL;
2252 /* We know the transferer is in the target_bridge, so take the other bridge off hold */
2254 return TRANSFER_COMPLETE;
2256 return TRANSFER_REBRIDGE;
2258 play_failsound(props->transferer);
2259 return TRANSFER_REBRIDGE;
2262 return TRANSFER_THREEWAY;
2264 hold(props->transferer);
2266 unhold(props->transferer);
2268 case STIMULUS_NONE:
2269 case STIMULUS_TIMEOUT:
2273 default:
2274 ast_log(LOG_WARNING, "Unexpected stimulus '%s' received in attended transfer state '%s'\n",
2275 stimulus_strs[stimulus], state_properties[props->state].state_name);
2276 return props->state;
2277 }
2278}

References ao2_ref, ast_bridge_merge_inhibit(), ast_log, bridge_basic_change_personality(), BRIDGE_BASIC_PERSONALITY_NORMAL, bridge_move(), bridge_unhold(), hold(), LOG_WARNING, NULL, play_failsound(), attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, STIMULUS_DTMF_ATXFER_ABORT, STIMULUS_DTMF_ATXFER_COMPLETE, STIMULUS_DTMF_ATXFER_SWAP, STIMULUS_DTMF_ATXFER_THREEWAY, STIMULUS_NONE, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_RECALL_TARGET_HANGUP, stimulus_strs, STIMULUS_TIMEOUT, STIMULUS_TRANSFER_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, STIMULUS_TRANSFERER_HANGUP, attended_transfer_properties::target_bridge, TRANSFER_COMPLETE, TRANSFER_DOUBLECHECKING, TRANSFER_FAIL, TRANSFER_REBRIDGE, TRANSFER_THREEWAY, attended_transfer_properties::transferee_bridge, attended_transfer_properties::transferer, and unhold().

◆ copy_caller_data()

static void copy_caller_data ( struct ast_channel dest,
struct ast_channel caller 
)
static

Definition at line 3276 of file bridge_basic.c.

3277{
3278 ast_channel_lock_both(caller, dest);
3280 ast_channel_inherit_variables(caller, dest);
3281 ast_channel_datastore_inherit(caller, dest);
3282 ast_channel_unlock(dest);
3283 ast_channel_unlock(caller);
3284}
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8293
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)

References ast_channel_caller(), ast_channel_connected(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock_both, ast_channel_unlock, and ast_connected_line_copy_from_caller().

Referenced by blind_transfer_cb(), and dial_transfer().

◆ dial_transfer()

static struct ast_channel * dial_transfer ( struct ast_channel caller,
const char *  destination 
)
static

Helper function that creates an outgoing channel and returns it immediately.

Definition at line 3287 of file bridge_basic.c.

3288{
3289 struct ast_channel *chan;
3290 int cause;
3291 struct ast_format_cap *caps;
3292
3293 ast_channel_lock(caller);
3294 caps = ao2_bump(ast_channel_nativeformats(caller));
3295 ast_channel_unlock(caller);
3296
3297 /* Now we request a local channel to prepare to call the destination */
3298 chan = ast_request("Local", caps, NULL, caller, destination, &cause);
3299
3300 ao2_cleanup(caps);
3301
3302 if (!chan) {
3303 return NULL;
3304 }
3305
3306 ast_channel_lock_both(chan, caller);
3307
3309
3310 /* Who is transferring the call. */
3311 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", ast_channel_name(caller));
3312
3314
3315 ast_channel_unlock(chan);
3316 ast_channel_unlock(caller);
3317
3318 /* Before we actually dial out let's inherit appropriate information. */
3319 copy_caller_data(chan, caller);
3320
3321 return chan;
3322}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int is_attended)
Set the relevant transfer variables for a single channel.
Definition: bridge.c:4352
@ AST_CHANNEL_REQUESTOR_BRIDGE_PEER
Definition: channel.h:1477
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6354
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.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54

References ao2_bump, ao2_cleanup, ast_bridge_set_transfer_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_name(), ast_channel_nativeformats(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_BRIDGE_PEER, ast_channel_unlock, ast_request(), copy_caller_data(), NULL, and pbx_builtin_setvar_helper().

Referenced by feature_attended_transfer().

◆ double_checking_enter()

static int double_checking_enter ( struct attended_transfer_properties props)
static

Definition at line 2280 of file bridge_basic.c.

2281{
2282 return 0;
2283}

◆ double_checking_exit()

static enum attended_transfer_state double_checking_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 2285 of file bridge_basic.c.

2287{
2288 switch (stimulus) {
2290 play_failsound(props->transferer);
2291 publish_transfer_fail(props);
2292 return TRANSFER_FAIL;
2295 /* We know the transferer is in the transferee, so take the other bridge off hold */
2297 return TRANSFER_COMPLETE;
2300 play_failsound(props->transferer);
2301 return TRANSFER_RESUME;
2304 return TRANSFER_THREEWAY;
2306 hold(props->transferer);
2308 unhold(props->transferer);
2309 return TRANSFER_CONSULTING;
2310 case STIMULUS_NONE:
2311 case STIMULUS_TIMEOUT:
2315 default:
2316 ast_log(LOG_WARNING, "Unexpected stimulus '%s' received in attended transfer state '%s'\n",
2317 stimulus_strs[stimulus], state_properties[props->state].state_name);
2318 return props->state;
2319 }
2320}

References ast_log, bridge_move(), bridge_unhold(), hold(), LOG_WARNING, NULL, play_failsound(), publish_transfer_fail(), attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, STIMULUS_DTMF_ATXFER_ABORT, STIMULUS_DTMF_ATXFER_COMPLETE, STIMULUS_DTMF_ATXFER_SWAP, STIMULUS_DTMF_ATXFER_THREEWAY, STIMULUS_NONE, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_RECALL_TARGET_HANGUP, stimulus_strs, STIMULUS_TIMEOUT, STIMULUS_TRANSFER_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, STIMULUS_TRANSFERER_HANGUP, attended_transfer_properties::target_bridge, TRANSFER_COMPLETE, TRANSFER_CONSULTING, TRANSFER_FAIL, TRANSFER_RESUME, TRANSFER_THREEWAY, attended_transfer_properties::transferee_bridge, attended_transfer_properties::transferer, and unhold().

◆ dtmf_features_flags_to_string()

static int dtmf_features_flags_to_string ( struct ast_flags feature_flags,
char *  buffer,
size_t  buffer_size 
)
static

Definition at line 133 of file bridge_basic.c.

134{
135 size_t buffer_expended = 0;
136 unsigned int cur_feature;
137 static const struct {
138 char letter;
139 unsigned int flag;
140 } associations[] = {
141 { 'T', AST_FEATURE_REDIRECT },
142 { 'K', AST_FEATURE_PARKCALL },
143 { 'H', AST_FEATURE_DISCONNECT },
144 { 'W', AST_FEATURE_AUTOMON },
145 { 'X', AST_FEATURE_AUTOMIXMON },
146 };
147
148 for (cur_feature = 0; cur_feature < ARRAY_LEN(associations); cur_feature++) {
149 if (ast_test_flag(feature_flags, associations[cur_feature].flag)) {
150 if (buffer_expended == buffer_size - 1) {
151 buffer[buffer_expended] = '\0';
152 return -1;
153 }
154 buffer[buffer_expended++] = associations[cur_feature].letter;
155 }
156 }
157
158 buffer[buffer_expended] = '\0';
159 return 0;
160}
@ AST_FEATURE_AUTOMIXMON
Definition: channel.h:1069
@ AST_FEATURE_REDIRECT
Definition: channel.h:1064
@ AST_FEATURE_PARKCALL
Definition: channel.h:1068
@ AST_FEATURE_AUTOMON
Definition: channel.h:1067
@ AST_FEATURE_DISCONNECT
Definition: channel.h:1065
long int flag
Definition: f2c.h:83
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, AST_FEATURE_AUTOMIXMON, AST_FEATURE_AUTOMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, and ast_test_flag.

Referenced by ast_bridge_features_ds_get_string().

◆ dynamic_dtmf_hook_add()

static int dynamic_dtmf_hook_add ( struct ast_bridge_features features,
unsigned int  flags,
const char *  dtmf,
const char *  feature_name,
const char *  app_name,
const char *  app_args,
const char *  moh_class 
)
static

Definition at line 543 of file bridge_basic.c.

544{
545 struct dynamic_dtmf_hook_data *hook_data;
546 size_t len_name = strlen(app_name) + 1;
547 size_t len_args = ast_strlen_zero(app_args) ? 0 : strlen(app_args) + 1;
548 size_t len_moh = ast_strlen_zero(moh_class) ? 0 : strlen(moh_class) + 1;
549 size_t len_feature = strlen(feature_name) + 1;
550 size_t len_data = sizeof(*hook_data) + len_name + len_args + len_moh + len_feature;
551 int res;
552
553 /* Fill in application run hook data. */
554 hook_data = ast_malloc(len_data);
555 if (!hook_data) {
556 return -1;
557 }
558 hook_data->flags = flags;
559 hook_data->app_args_offset = len_args ? len_name : 0;
560 hook_data->moh_offset = len_moh ? len_name + len_args : 0;
561 hook_data->feature_offset = len_name + len_args + len_moh;
562 strcpy(hook_data->app_name, app_name);/* Safe */
563 if (len_args) {
564 strcpy(&hook_data->app_name[hook_data->app_args_offset], app_args);/* Safe */
565 }
566 if (len_moh) {
567 strcpy(&hook_data->app_name[hook_data->moh_offset], moh_class);/* Safe */
568 }
569 strcpy(&hook_data->app_name[hook_data->feature_offset], feature_name);/* Safe */
570
571 res = ast_bridge_dtmf_hook(features, dtmf, dynamic_dtmf_hook_trip, hook_data,
574 if (res) {
575 ast_free(hook_data);
576 }
577 return res;
578}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
static int dynamic_dtmf_hook_trip(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Definition: bridge_basic.c:475
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463

References dynamic_dtmf_hook_data::app_args_offset, app_name(), dynamic_dtmf_hook_data::app_name, ast_bridge_dtmf_hook(), AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE, AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_free, ast_free_ptr(), ast_malloc, ast_strlen_zero(), dynamic_dtmf_hook_trip(), dynamic_dtmf_hook_data::feature_offset, dynamic_dtmf_hook_data::flags, and dynamic_dtmf_hook_data::moh_offset.

Referenced by setup_dynamic_feature().

◆ dynamic_dtmf_hook_callback()

static void dynamic_dtmf_hook_callback ( struct ast_bridge_channel bridge_channel,
const void *  payload,
size_t  payload_size 
)
static

Definition at line 435 of file bridge_basic.c.

437{
438 struct ast_channel *chan = bridge_channel->chan;
439 const struct dynamic_dtmf_hook_run *run_data = payload;
440
441 pbx_builtin_setvar_helper(chan, "DYNAMIC_FEATURENAME",
442 &run_data->app_name[run_data->feature_offset]);
443 pbx_builtin_setvar_helper(chan, "DYNAMIC_WHO_ACTIVATED",
444 &run_data->app_name[run_data->activated_offset]);
445
446 ast_bridge_channel_run_app(bridge_channel, run_data->app_name,
447 run_data->app_args_offset ? &run_data->app_name[run_data->app_args_offset] : NULL,
448 run_data->moh_offset ? &run_data->app_name[run_data->moh_offset] : NULL);
449}
void ast_bridge_channel_run_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
Run an application on the bridge channel.
struct ast_bridge_channel * bridge_channel

References dynamic_dtmf_hook_run::activated_offset, dynamic_dtmf_hook_run::app_args_offset, dynamic_dtmf_hook_run::app_name, ast_bridge_channel_run_app(), ast_channel::bridge_channel, ast_bridge_channel::chan, dynamic_dtmf_hook_run::feature_offset, dynamic_dtmf_hook_run::moh_offset, NULL, and pbx_builtin_setvar_helper().

Referenced by dynamic_dtmf_hook_trip().

◆ dynamic_dtmf_hook_trip()

static int dynamic_dtmf_hook_trip ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Definition at line 475 of file bridge_basic.c.

476{
477 struct dynamic_dtmf_hook_data *pvt = hook_pvt;
478 struct dynamic_dtmf_hook_run *run_data;
479 const char *activated_name;
480 size_t len_name;
481 size_t len_args;
482 size_t len_moh;
483 size_t len_feature;
484 size_t len_activated;
485 size_t len_data;
486
487 /* Determine lengths of things. */
488 len_name = strlen(pvt->app_name) + 1;
489 len_args = pvt->app_args_offset ? strlen(&pvt->app_name[pvt->app_args_offset]) + 1 : 0;
490 len_moh = pvt->moh_offset ? strlen(&pvt->app_name[pvt->moh_offset]) + 1 : 0;
491 len_feature = strlen(&pvt->app_name[pvt->feature_offset]) + 1;
492 ast_channel_lock(bridge_channel->chan);
493 activated_name = ast_strdupa(ast_channel_name(bridge_channel->chan));
494 ast_channel_unlock(bridge_channel->chan);
495 len_activated = strlen(activated_name) + 1;
496 len_data = sizeof(*run_data) + len_name + len_args + len_moh + len_feature + len_activated;
497
498 /* Fill in dynamic feature run hook data. */
499 run_data = ast_alloca(len_data);
500 run_data->app_args_offset = len_args ? len_name : 0;
501 run_data->moh_offset = len_moh ? len_name + len_args : 0;
502 run_data->feature_offset = len_name + len_args + len_moh;
503 run_data->activated_offset = len_name + len_args + len_moh + len_feature;
504 strcpy(run_data->app_name, pvt->app_name);/* Safe */
505 if (len_args) {
506 strcpy(&run_data->app_name[run_data->app_args_offset],
507 &pvt->app_name[pvt->app_args_offset]);/* Safe */
508 }
509 if (len_moh) {
510 strcpy(&run_data->app_name[run_data->moh_offset],
511 &pvt->app_name[pvt->moh_offset]);/* Safe */
512 }
513 strcpy(&run_data->app_name[run_data->feature_offset],
514 &pvt->app_name[pvt->feature_offset]);/* Safe */
515 strcpy(&run_data->app_name[run_data->activated_offset], activated_name);/* Safe */
516
520 dynamic_dtmf_hook_callback, run_data, len_data);
521 } else {
522 dynamic_dtmf_hook_callback(bridge_channel, run_data, len_data);
523 }
524 return 0;
525}
static void dynamic_dtmf_hook_callback(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Definition: bridge_basic.c:435
@ AST_BRIDGE_CHANNEL_CB_OPTION_MEDIA
int ast_bridge_channel_write_callback(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
Write a bridge action custom callback frame into the bridge.
@ AST_FEATURE_FLAG_ONPEER
Definition: features.h:35

References dynamic_dtmf_hook_run::activated_offset, dynamic_dtmf_hook_run::app_args_offset, dynamic_dtmf_hook_data::app_args_offset, dynamic_dtmf_hook_run::app_name, dynamic_dtmf_hook_data::app_name, ast_alloca, AST_BRIDGE_CHANNEL_CB_OPTION_MEDIA, ast_bridge_channel_write_callback(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, AST_FEATURE_FLAG_ONPEER, ast_strdupa, ast_test_flag, ast_bridge_channel::chan, dynamic_dtmf_hook_callback(), dynamic_dtmf_hook_run::feature_offset, dynamic_dtmf_hook_data::feature_offset, dynamic_dtmf_hook_run::moh_offset, and dynamic_dtmf_hook_data::moh_offset.

Referenced by dynamic_dtmf_hook_add().

◆ fail_enter()

static int fail_enter ( struct attended_transfer_properties props)
static

Definition at line 2741 of file bridge_basic.c.

2742{
2743 if (props->transferee_bridge) {
2745 props->transferee_bridge = NULL;
2746 }
2747 return 0;
2748}

References ast_bridge_destroy(), NULL, and attended_transfer_properties::transferee_bridge.

◆ feature_attended_transfer()

static int feature_attended_transfer ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Internal built in feature for attended transfers.

This hook will set up a thread for monitoring the progress of an attended transfer. For more information about attended transfer progress, see documentation on the transfer state machine.

Parameters
bridge_channelThe channel that pressed the attended transfer DTMF sequence
hook_pvtStructure with further information about the attended transfer

Definition at line 3334 of file bridge_basic.c.

3335{
3336 struct ast_bridge_features_attended_transfer *attended_transfer = hook_pvt;
3337 struct attended_transfer_properties *props;
3338 struct ast_bridge *bridge;
3339 char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 1];
3340 char exten[AST_MAX_EXTENSION] = "";
3341 pthread_t thread;
3342
3343 /* Inhibit the bridge before we do anything else. */
3344 bridge = ast_bridge_channel_merge_inhibit(bridge_channel, +1);
3345
3346 ast_verb(3, "Channel %s: Started DTMF attended transfer.\n",
3347 ast_channel_name(bridge_channel->chan));
3348
3349 if (strcmp(bridge->v_table->name, "basic")) {
3350 ast_log(LOG_ERROR, "Channel %s: Attended transfer attempted on unsupported bridge type '%s'.\n",
3351 ast_channel_name(bridge_channel->chan), bridge->v_table->name);
3352 ast_bridge_merge_inhibit(bridge, -1);
3353 ao2_ref(bridge, -1);
3354 return 0;
3355 }
3356
3357 /* Was the bridge inhibited before we inhibited it? */
3358 if (1 < bridge->inhibit_merge) {
3359 /*
3360 * The peer likely initiated attended transfer at the same time
3361 * and we lost the race.
3362 */
3363 ast_verb(3, "Channel %s: Bridge '%s' does not permit merging at this time.\n",
3364 ast_channel_name(bridge_channel->chan), bridge->uniqueid);
3365 ast_bridge_merge_inhibit(bridge, -1);
3366 ao2_ref(bridge, -1);
3367 return 0;
3368 }
3369
3370 props = attended_transfer_properties_alloc(bridge_channel->chan,
3371 attended_transfer ? attended_transfer->context : NULL);
3372 if (!props) {
3373 ast_log(LOG_ERROR, "Channel %s: Unable to allocate control structure for performing attended transfer.\n",
3374 ast_channel_name(bridge_channel->chan));
3375 ast_bridge_merge_inhibit(bridge, -1);
3376 ao2_ref(bridge, -1);
3377 return 0;
3378 }
3379
3380 props->transferee_bridge = bridge;
3381
3382 if (add_transferer_role(props->transferer, attended_transfer)) {
3383 ast_log(LOG_ERROR, "Channel %s: Unable to set transferrer bridge role.\n",
3384 ast_channel_name(bridge_channel->chan));
3386 return 0;
3387 }
3388
3389 ast_bridge_channel_write_hold(bridge_channel, NULL);
3390
3391 /* Grab the extension to transfer to */
3392 if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), props->context)) {
3393 /*
3394 * This is a normal exit for when the user fails
3395 * to specify a valid transfer target. e.g., The user
3396 * hungup, didn't dial any digits, or dialed an invalid
3397 * extension.
3398 */
3399 ast_verb(3, "Channel %s: Unable to acquire target extension for attended transfer.\n",
3400 ast_channel_name(bridge_channel->chan));
3401 ast_bridge_channel_write_unhold(bridge_channel);
3403 return 0;
3404 }
3405
3406 ast_string_field_set(props, exten, exten);
3407
3408 /* Fill the variable with the extension and context we want to call */
3409 snprintf(destination, sizeof(destination), "%s@%s", props->exten, props->context);
3410
3411 ast_debug(1, "Channel %s: Attended transfer target '%s'\n",
3412 ast_channel_name(bridge_channel->chan), destination);
3413
3414 /* Get a channel that is the destination we wish to call */
3415 props->transfer_target = dial_transfer(bridge_channel->chan, destination);
3416 if (!props->transfer_target) {
3417 ast_log(LOG_ERROR, "Channel %s: Unable to request outbound channel for attended transfer target.\n",
3418 ast_channel_name(bridge_channel->chan));
3420 ast_bridge_channel_write_unhold(bridge_channel);
3422 return 0;
3423 }
3424
3425
3426 /* Create a bridge to use to talk to the person we are calling */
3428 if (!props->target_bridge) {
3429 ast_log(LOG_ERROR, "Channel %s: Unable to create bridge for attended transfer target.\n",
3430 ast_channel_name(bridge_channel->chan));
3432 ast_bridge_channel_write_unhold(bridge_channel);
3434 props->transfer_target = NULL;
3436 return 0;
3437 }
3439
3440 if (attach_framehook(props, props->transfer_target)) {
3441 ast_log(LOG_ERROR, "Channel %s: Unable to attach framehook to transfer target.\n",
3442 ast_channel_name(bridge_channel->chan));
3444 ast_bridge_channel_write_unhold(bridge_channel);
3446 props->transfer_target = NULL;
3448 return 0;
3449 }
3450
3455
3456 if (ast_call(props->transfer_target, destination, 0)) {
3457 ast_log(LOG_ERROR, "Channel %s: Unable to place outbound call to transfer target.\n",
3458 ast_channel_name(bridge_channel->chan));
3460 ast_bridge_channel_write_unhold(bridge_channel);
3462 props->transfer_target = NULL;
3464 return 0;
3465 }
3466
3467 /* We increase the refcount of the transfer target because ast_bridge_impart() will
3468 * steal the reference we already have. We need to keep a reference, so the only
3469 * choice is to give it a bump
3470 */
3474 ast_log(LOG_ERROR, "Channel %s: Unable to place transfer target into bridge.\n",
3475 ast_channel_name(bridge_channel->chan));
3477 ast_bridge_channel_write_unhold(bridge_channel);
3479 props->transfer_target = NULL;
3481 return 0;
3482 }
3483
3485 ast_log(LOG_ERROR, "Channel %s: Unable to create monitoring thread for attended transfer.\n",
3486 ast_channel_name(bridge_channel->chan));
3488 ast_bridge_channel_write_unhold(bridge_channel);
3490 return 0;
3491 }
3492
3493 /* Once the monitoring thread has been created, it is responsible for destroying all
3494 * of the necessary components.
3495 */
3496 return 0;
3497}
pthread_t thread
Definition: app_sla.c:329
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:590
static struct attended_transfer_properties * attended_transfer_properties_alloc(struct ast_channel *transferer, const char *context)
Allocate and initialize attended transfer properties.
static void stream_failsound(struct ast_channel *chan)
Helper method to stream a fail sound on a channel.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
static struct ast_channel * dial_transfer(struct ast_channel *caller, const char *destination)
Helper function that creates an outgoing channel and returns it immediately.
static int add_transferer_role(struct ast_channel *chan, struct ast_bridge_features_attended_transfer *attended_transfer)
static void * attended_transfer_monitor_thread(void *data)
The main loop for the attended transfer monitor thread.
static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len, const char *context)
Helper function that presents dialtone and grabs extension.
static int attach_framehook(struct attended_transfer_properties *props, struct ast_channel *channel)
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
struct ast_bridge * ast_bridge_channel_merge_inhibit(struct ast_bridge_channel *bridge_channel, int request)
Adjust the bridge_channel's bridge merge inhibit request count.
int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, const char *moh_class)
Write a hold frame into the bridge.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6461
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define AST_MAX_CONTEXT
Definition: channel.h:135
#define AST_MAX_EXTENSION
Definition: channel.h:134
#define ast_verb(level,...)
Structure that contains configuration information for the attended transfer built in feature.
const struct ast_bridge_methods * v_table
Definition: bridge.h:351
const ast_string_field uniqueid
Definition: bridge.h:401
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed.
Definition: bridge.h:384
const ast_string_field context
const ast_string_field exten
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588

References add_transferer_role(), ao2_ref, ast_bridge_basic_new(), ast_bridge_channel_merge_inhibit(), ast_bridge_channel_write_hold(), ast_bridge_channel_write_unhold(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_bridge_merge_inhibit(), ast_call(), ast_channel_name(), ast_channel_ref, ast_debug, ast_hangup(), ast_log, AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_pthread_create_detached, ast_string_field_set, ast_verb, attach_framehook(), attended_transfer_monitor_thread(), attended_transfer_properties_alloc(), attended_transfer_properties_shutdown(), bridge_basic_change_personality(), BRIDGE_BASIC_PERSONALITY_ATXFER, ast_bridge_channel::chan, ast_bridge_features_attended_transfer::context, attended_transfer_properties::context, dial_transfer(), attended_transfer_properties::exten, grab_transfer(), ast_bridge::inhibit_merge, LOG_ERROR, ast_bridge_methods::name, NULL, stream_failsound(), attended_transfer_properties::target_bridge, thread, attended_transfer_properties::transfer_target, attended_transfer_properties::transferee_bridge, attended_transfer_properties::transferer, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by ast_bridging_init_basic().

◆ feature_blind_transfer()

static int feature_blind_transfer ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Internal built in feature for blind transfers.

Definition at line 3510 of file bridge_basic.c.

3511{
3512 char xfer_exten[AST_MAX_EXTENSION] = "";
3513 struct ast_bridge_features_blind_transfer *blind_transfer = hook_pvt;
3514 const char *xfer_context;
3515 char *goto_on_blindxfer;
3516
3517 ast_verb(3, "Channel %s: Started DTMF blind transfer.\n",
3518 ast_channel_name(bridge_channel->chan));
3519
3520 ast_bridge_channel_write_hold(bridge_channel, NULL);
3521
3522 ast_channel_lock(bridge_channel->chan);
3523 xfer_context = ast_strdupa(get_transfer_context(bridge_channel->chan,
3524 blind_transfer ? blind_transfer->context : NULL));
3525 goto_on_blindxfer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(bridge_channel->chan,
3526 "GOTO_ON_BLINDXFR"), ""));
3527 ast_channel_unlock(bridge_channel->chan);
3528
3529 /* Grab the extension to transfer to */
3530 if (grab_transfer(bridge_channel->chan, xfer_exten, sizeof(xfer_exten), xfer_context)) {
3531 ast_bridge_channel_write_unhold(bridge_channel);
3532 return 0;
3533 }
3534
3535 ast_debug(1, "Channel %s: Blind transfer target '%s@%s'\n",
3536 ast_channel_name(bridge_channel->chan), xfer_exten, xfer_context);
3537
3538 if (!ast_strlen_zero(goto_on_blindxfer)) {
3539 const char *chan_context;
3540 const char *chan_exten;
3541 int chan_priority;
3542
3543 ast_debug(1, "Channel %s: After transfer, transferrer goes to %s\n",
3544 ast_channel_name(bridge_channel->chan), goto_on_blindxfer);
3545
3546 ast_channel_lock(bridge_channel->chan);
3547 chan_context = ast_strdupa(ast_channel_context(bridge_channel->chan));
3548 chan_exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
3549 chan_priority = ast_channel_priority(bridge_channel->chan);
3550 ast_channel_unlock(bridge_channel->chan);
3551 ast_bridge_set_after_go_on(bridge_channel->chan,
3552 chan_context, chan_exten, chan_priority, goto_on_blindxfer);
3553 }
3554
3555 if (ast_bridge_transfer_blind(0, bridge_channel->chan, xfer_exten, xfer_context,
3557 && !ast_strlen_zero(goto_on_blindxfer)) {
3558 ast_bridge_discard_after_goto(bridge_channel->chan);
3559 }
3560
3561 return 0;
3562}
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
Definition: bridge.c:4425
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:384
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
Definition: bridge_after.c:622
static void blind_transfer_cb(struct ast_channel *new_channel, struct transfer_channel_data *user_data_wrapper, enum ast_transfer_type transfer_type)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Structure that contains configuration information for the blind transfer built in feature.

References ast_bridge_channel_write_hold(), ast_bridge_channel_write_unhold(), ast_bridge_discard_after_goto(), ast_bridge_set_after_go_on(), ast_bridge_transfer_blind(), AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_name(), ast_channel_priority(), ast_channel_unlock, ast_debug, AST_MAX_EXTENSION, ast_strdupa, ast_strlen_zero(), ast_verb, blind_transfer_cb(), ast_bridge_channel::chan, ast_bridge_features_blind_transfer::context, get_transfer_context(), grab_transfer(), NULL, pbx_builtin_getvar_helper(), and S_OR.

Referenced by ast_bridging_init_basic().

◆ get_transfer_context()

static const char * get_transfer_context ( struct ast_channel transferer,
const char *  context 
)
static

Definition at line 1379 of file bridge_basic.c.

1380{
1381 if (!ast_strlen_zero(context)) {
1382 return context;
1383 }
1384 context = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1385 if (!ast_strlen_zero(context)) {
1386 return context;
1387 }
1388 context = ast_channel_context(transferer);
1389 if (!ast_strlen_zero(context)) {
1390 return context;
1391 }
1392 return "default";
1393}

References ast_channel_context(), ast_strlen_zero(), voicemailpwcheck::context, pbx_builtin_getvar_helper(), and attended_transfer_properties::transferer.

Referenced by attended_transfer_properties_alloc(), and feature_blind_transfer().

◆ get_transfer_exten()

static const char * get_transfer_exten ( struct ast_channel transferer,
const char *  exten 
)
static

Definition at line 1404 of file bridge_basic.c.

1405{
1406 if (!ast_strlen_zero(exten)) {
1407 return exten;
1408 }
1409 exten = pbx_builtin_getvar_helper(transferer, "TRANSFER_EXTEN");
1410 if (!ast_strlen_zero(exten)) {
1411 return exten;
1412 }
1413 return ""; /* empty default, to get transfer extension from user now */
1414}

References ast_strlen_zero(), attended_transfer_properties::exten, pbx_builtin_getvar_helper(), and attended_transfer_properties::transferer.

Referenced by grab_transfer().

◆ get_transfer_parties()

static void get_transfer_parties ( struct ast_channel transferer,
struct ast_bridge transferee_bridge,
struct ast_bridge target_bridge,
struct ast_channel **  transferee,
struct ast_channel **  transfer_target 
)
static

determine transferee and transfer target for an attended transfer

In builtin attended transfers, there is a single transferer channel that jumps between the two bridges involved. At the time the attended transfer occurs, the transferer could be in either bridge, so determining the parties is a bit more complex than normal.

The method used here is to determine which of the two bridges the transferer is in, and grabbing the peer from that bridge. The other bridge, if it only has a single channel in it, has the other desired channel.

Parameters
transfererThe channel performing the transfer
transferee_bridgeThe bridge that the transferee is in
target_bridgeThe bridge that the transfer target is in
[out]transfereeThe transferee channel
[out]transfer_targetThe transfer target channel

Definition at line 1634 of file bridge_basic.c.

1637{
1638 struct ast_bridge *transferer_bridge;
1639
1640 ast_channel_lock(transferer);
1641 transferer_bridge = ast_channel_get_bridge(transferer);
1642 ast_channel_unlock(transferer);
1643
1644 if (transferer_bridge == transferee_bridge) {
1645 get_transfer_parties_transferer_bridge(transferee_bridge, target_bridge,
1646 transferer, transferee, transfer_target);
1647 } else if (transferer_bridge == target_bridge) {
1648 get_transfer_parties_transferer_bridge(target_bridge, transferee_bridge,
1649 transferer, transfer_target, transferee);
1650 } else {
1651 get_transfer_party_non_transferer_bridge(transferee_bridge, transferee);
1652 get_transfer_party_non_transferer_bridge(target_bridge, transfer_target);
1653 }
1654
1655 ao2_cleanup(transferer_bridge);
1656}
static void get_transfer_parties_transferer_bridge(struct ast_bridge *transferer_bridge, struct ast_bridge *other_bridge, struct ast_channel *transferer, struct ast_channel **transferer_peer, struct ast_channel **other_party)
Get the transferee and transfer target when the transferer is in a bridge with one of the desired par...
static void get_transfer_party_non_transferer_bridge(struct ast_bridge *bridge, struct ast_channel **party)
Get a desired transfer party for a bridge the transferer is not in.
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10534

References ao2_cleanup, ast_channel_get_bridge(), ast_channel_lock, ast_channel_unlock, get_transfer_parties_transferer_bridge(), and get_transfer_party_non_transferer_bridge().

Referenced by blond_enter(), complete_enter(), and threeway_enter().

◆ get_transfer_parties_transferer_bridge()

static void get_transfer_parties_transferer_bridge ( struct ast_bridge transferer_bridge,
struct ast_bridge other_bridge,
struct ast_channel transferer,
struct ast_channel **  transferer_peer,
struct ast_channel **  other_party 
)
static

Get the transferee and transfer target when the transferer is in a bridge with one of the desired parties.

Parameters
transferer_bridgeThe bridge the transferer is in
other_bridgeThe bridge the transferer is not in. May be NULL.
transfererThe transferer party
[out]transferer_peerThe party that is in the bridge with the transferer
[out]other_partyThe party that is in the other_bridge

Definition at line 1609 of file bridge_basic.c.

1612{
1613 *transferer_peer = ast_bridge_peer(transferer_bridge, transferer);
1614 get_transfer_party_non_transferer_bridge(other_bridge, other_party);
1615}
struct ast_channel * ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: bridge.c:4075

References ast_bridge_peer(), and get_transfer_party_non_transferer_bridge().

Referenced by get_transfer_parties().

◆ get_transfer_party_non_transferer_bridge()

static void get_transfer_party_non_transferer_bridge ( struct ast_bridge bridge,
struct ast_channel **  party 
)
static

Get a desired transfer party for a bridge the transferer is not in.

Parameters
bridgeThe bridge to get the party from. May be NULL.
[out]partyThe lone channel in the bridge. Will be set NULL if bridge is NULL or multiple parties are present.

Definition at line 1589 of file bridge_basic.c.

1591{
1592 if (bridge && bridge->num_channels == 1) {
1593 *party = ast_channel_ref(AST_LIST_FIRST(&bridge->channels)->chan);
1594 } else {
1595 *party = NULL;
1596 }
1597}
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
unsigned int num_channels
Definition: bridge.h:373

References ast_channel_ref, AST_LIST_FIRST, ast_bridge::channels, NULL, and ast_bridge::num_channels.

Referenced by get_transfer_parties(), and get_transfer_parties_transferer_bridge().

◆ grab_transfer()

static int grab_transfer ( struct ast_channel chan,
char *  exten,
size_t  exten_len,
const char *  context 
)
static

Helper function that presents dialtone and grabs extension.

Return values
0on success
-1on failure

Definition at line 3174 of file bridge_basic.c.

3175{
3176 int res;
3177 int digit_timeout;
3178 int attempts = 0;
3179 int max_attempts;
3180 struct ast_features_xfer_config *xfer_cfg;
3181 char *announce_sound, *retry_sound, *invalid_sound;
3182 const char *extenoverride;
3183
3184 ast_channel_lock(chan);
3185 extenoverride = get_transfer_exten(chan, NULL);
3186
3187 if (!ast_strlen_zero(extenoverride)) {
3188 int extenres = ast_exists_extension(chan, context, extenoverride, 1,
3189 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)) ? 1 : 0;
3190 if (extenres) {
3191 ast_copy_string(exten, extenoverride, exten_len);
3192 ast_channel_unlock(chan);
3193 ast_verb(3, "Transfering call to '%s@%s'", exten, context);
3194 return 0;
3195 }
3196 ast_log(LOG_WARNING, "Override extension '%s' does not exist in context '%s'\n", extenoverride, context);
3197 /* since we didn't get a valid extension from the channel, fall back and grab it from the user as usual now */
3198 }
3199
3200 xfer_cfg = ast_get_chan_features_xfer_config(chan);
3201 if (!xfer_cfg) {
3202 ast_log(LOG_ERROR, "Channel %s: Unable to get transfer configuration\n",
3203 ast_channel_name(chan));
3204 ast_channel_unlock(chan);
3205 return -1;
3206 }
3207 digit_timeout = xfer_cfg->transferdigittimeout * 1000;
3208 max_attempts = xfer_cfg->transferdialattempts;
3209 announce_sound = ast_strdupa(xfer_cfg->transferannouncesound);
3210 retry_sound = ast_strdupa(xfer_cfg->transferretrysound);
3211 invalid_sound = ast_strdupa(xfer_cfg->transferinvalidsound);
3212 ao2_ref(xfer_cfg, -1);
3213 ast_channel_unlock(chan);
3214
3215 /* Play the simple "transfer" prompt out and wait */
3216 if (!ast_strlen_zero(announce_sound)) {
3217 res = ast_stream_and_wait(chan, announce_sound, AST_DIGIT_ANY);
3218 ast_stopstream(chan);
3219 if (res < 0) {
3220 /* Hangup or error */
3221 return -1;
3222 }
3223 if (res) {
3224 /* Store the DTMF digit that interrupted playback of the file. */
3225 exten[0] = res;
3226 }
3227 }
3228
3229 /* Drop to dialtone so they can enter the extension they want to transfer to */
3230 do {
3231 ++attempts;
3232
3233 ast_test_suite_event_notify("TRANSFER_BEGIN_DIAL",
3234 "Channel: %s\r\n"
3235 "Attempt: %d",
3236 ast_channel_name(chan), attempts);
3237 res = ast_app_dtget(chan, context, exten, exten_len, exten_len - 1, digit_timeout);
3238 ast_test_suite_event_notify("TRANSFER_DIALLED",
3239 "Channel: %s\r\n"
3240 "Attempt: %d\r\n"
3241 "Dialled: %s\r\n"
3242 "Result: %s",
3243 ast_channel_name(chan), attempts, exten, res > 0 ? "Success" : "Failure");
3244 if (res < 0) {
3245 /* Hangup or error */
3246 res = -1;
3247 } else if (!res) {
3248 /* 0 for invalid extension dialed. */
3249 if (ast_strlen_zero(exten)) {
3250 ast_verb(3, "Channel %s: Dialed no digits.\n", ast_channel_name(chan));
3251 } else {
3252 ast_verb(3, "Channel %s: Dialed '%s@%s' does not exist.\n",
3253 ast_channel_name(chan), exten, context);
3254 }
3255 if (attempts < max_attempts) {
3256 ast_stream_and_wait(chan, retry_sound, AST_DIGIT_NONE);
3257 } else {
3258 ast_stream_and_wait(chan, invalid_sound, AST_DIGIT_NONE);
3259 }
3260 memset(exten, 0, exten_len);
3261 res = 1;
3262 } else {
3263 /* Dialed extension is valid. */
3264 res = 0;
3265 }
3266 } while (res > 0 && attempts < max_attempts);
3267
3268 ast_test_suite_event_notify("TRANSFER_DIAL_FINAL",
3269 "Channel: %s\r\n"
3270 "Result: %s",
3271 ast_channel_name(chan), res == 0 ? "Success" : "Failure");
3272
3273 return res ? -1 : 0;
3274}
static const char * get_transfer_exten(struct ast_channel *transferer, const char *exten)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1878
#define AST_DIGIT_NONE
Definition: file.h:47
#define AST_DIGIT_ANY
Definition: file.h:48
int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout)
Present a dialtone and collect a certain length extension.
Definition: main/app.c:138
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
#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
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
const ast_string_field transferannouncesound
Number structure.
Definition: app_followme.c:154
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189

References ao2_ref, ast_app_dtget(), ast_channel_caller(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), AST_DIGIT_ANY, AST_DIGIT_NONE, ast_exists_extension(), ast_get_chan_features_xfer_config(), ast_log, ast_stopstream(), ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, voicemailpwcheck::context, get_transfer_exten(), LOG_ERROR, LOG_WARNING, NULL, S_COR, ast_features_xfer_config::transferannouncesound, ast_features_xfer_config::transferdialattempts, ast_features_xfer_config::transferdigittimeout, ast_features_xfer_config::transferinvalidsound, and ast_features_xfer_config::transferretrysound.

Referenced by feature_attended_transfer(), and feature_blind_transfer().

◆ hesitant_enter()

static int hesitant_enter ( struct attended_transfer_properties props)
static

◆ hesitant_exit()

static enum attended_transfer_state hesitant_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 2163 of file bridge_basic.c.

2165{
2166 switch (stimulus) {
2168 play_failsound(props->transferer);
2169 publish_transfer_fail(props);
2170 return TRANSFER_FAIL;
2177 case STIMULUS_TIMEOUT:
2179 play_failsound(props->transferer);
2180 return TRANSFER_RESUME;
2182 return TRANSFER_THREEWAY;
2184 hold(props->transferer);
2186 case STIMULUS_NONE:
2189 default:
2190 ast_log(LOG_WARNING, "Unexpected stimulus '%s' received in attended transfer state '%s'\n",
2191 stimulus_strs[stimulus], state_properties[props->state].state_name);
2192 return props->state;
2193 }
2194}

References ast_log, attended_transfer_properties::atxferdropcall, hold(), LOG_WARNING, play_failsound(), publish_transfer_fail(), attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, STIMULUS_DTMF_ATXFER_ABORT, STIMULUS_DTMF_ATXFER_COMPLETE, STIMULUS_DTMF_ATXFER_SWAP, STIMULUS_DTMF_ATXFER_THREEWAY, STIMULUS_NONE, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_RECALL_TARGET_HANGUP, stimulus_strs, STIMULUS_TIMEOUT, STIMULUS_TRANSFER_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, STIMULUS_TRANSFERER_HANGUP, TRANSFER_BLOND, TRANSFER_BLOND_NONFINAL, TRANSFER_CALLING_TARGET, TRANSFER_DOUBLECHECKING, TRANSFER_FAIL, TRANSFER_RESUME, TRANSFER_THREEWAY, and attended_transfer_properties::transferer.

◆ hold()

static void hold ( struct ast_channel chan)
static

Helper method to place a channel in a bridge on hold.

Definition at line 1788 of file bridge_basic.c.

1789{
1790 struct ast_bridge_channel *bridge_channel;
1791
1792 if (!chan) {
1793 return;
1794 }
1795
1797 bridge_channel = ast_channel_get_bridge_channel(chan);
1799
1800 if (bridge_channel) {
1801 ast_bridge_channel_write_hold(bridge_channel, NULL);
1802 ao2_ref(bridge_channel, -1);
1803 }
1804}

References ao2_ref, ast_bridge_channel_write_hold(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, ast_bridge_channel::chan, and NULL.

Referenced by bridge_hold(), consulting_exit(), double_checking_exit(), hesitant_exit(), and sla_hold_str().

◆ init_details()

static void init_details ( struct personality_details details,
enum bridge_basic_personality_type  type 
)
static

Definition at line 3613 of file bridge_basic.c.

3615{
3616 switch (type) {
3619 details->bridge_flags = NORMAL_FLAGS;
3621 break;
3624 details->bridge_flags = TRANSFER_FLAGS;
3625 break;
3626 default:
3627 ast_log(LOG_WARNING, "Asked to initialize unexpected basic bridge personality type.\n");
3628 break;
3629 }
3630}
#define TRANSFER_FLAGS
Definition: bridge_basic.c:54
static void on_personality_change_normal(struct ast_bridge *bridge)

References ast_log, BRIDGE_BASIC_PERSONALITY_ATXFER, BRIDGE_BASIC_PERSONALITY_NORMAL, personality_details::bridge_flags, LOG_WARNING, NORMAL_FLAGS, personality_details::on_personality_change, on_personality_change_normal(), personality_atxfer_v_table, personality_normal_v_table, TRANSFER_FLAGS, type, and personality_details::v_table.

Referenced by bridge_basic_personality_alloc().

◆ on_personality_change_normal()

static void on_personality_change_normal ( struct ast_bridge bridge)
static

Definition at line 3601 of file bridge_basic.c.

3602{
3603 struct ast_bridge_channel *iter;
3604
3606 if (add_normal_hooks(bridge, iter)) {
3607 ast_log(LOG_WARNING, "Unable to set up bridge hooks for channel %s. Features may not work properly\n",
3608 ast_channel_name(iter->chan));
3609 }
3610 }
3611}

References add_normal_hooks(), ast_channel_name(), AST_LIST_TRAVERSE, ast_log, ast_bridge_channel::bridge, ast_bridge_channel::chan, ast_bridge::channels, and LOG_WARNING.

Referenced by init_details().

◆ personality_destructor()

static void personality_destructor ( void *  obj)
static

Definition at line 3591 of file bridge_basic.c.

3592{
3593 struct bridge_basic_personality *personality = obj;
3594 int i;
3595
3596 for (i = 0; i < BRIDGE_BASIC_PERSONALITY_END; ++i) {
3597 ao2_cleanup(personality->details[i].pvt);
3598 }
3599}

References ao2_cleanup, BRIDGE_BASIC_PERSONALITY_END, bridge_basic_personality::details, and personality_details::pvt.

Referenced by bridge_basic_personality_alloc().

◆ play_failsound()

static void play_failsound ( struct ast_channel chan)
static

Helper method to play a fail sound on a channel in a bridge.

Parameters
chanThe channel to play the fail sound to

Definition at line 1752 of file bridge_basic.c.

1753{
1754 char *sound;
1755
1756 ast_channel_lock(chan);
1758 ast_channel_unlock(chan);
1759
1760 if (sound) {
1761 play_sound(chan, sound);
1762 ast_free(sound);
1763 }
1764}
char * ast_get_chan_features_xferfailsound(struct ast_channel *chan)
Get the transfer configuration option xferfailsound.

References ast_channel_lock, ast_channel_unlock, ast_free, ast_get_chan_features_xferfailsound(), ast_bridge_channel::chan, and play_sound().

Referenced by calling_target_exit(), consulting_exit(), double_checking_exit(), and hesitant_exit().

◆ play_sound()

static void play_sound ( struct ast_channel chan,
const char *  sound 
)
static

Helper method to play a sound on a channel in a bridge.

Parameters
chanThe channel to play the sound to
soundThe sound to play

Definition at line 1733 of file bridge_basic.c.

1734{
1735 struct ast_bridge_channel *bridge_channel;
1736
1738 bridge_channel = ast_channel_get_bridge_channel(chan);
1740
1741 if (bridge_channel) {
1742 ast_bridge_channel_queue_playfile(bridge_channel, NULL, sound, NULL);
1743 ao2_ref(bridge_channel, -1);
1744 }
1745}
int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Queue a bridge action play file frame onto the bridge channel.

References ao2_ref, ast_bridge_channel_queue_playfile(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, ast_bridge_channel::chan, and NULL.

Referenced by complete_enter(), play_failsound(), and threeway_enter().

◆ publish_transfer_fail()

static void publish_transfer_fail ( struct attended_transfer_properties props)
static

Send a stasis publication for a failed attended transfer.

Definition at line 1708 of file bridge_basic.c.

1709{
1710 struct ast_attended_transfer_message *transfer_msg;
1711
1712 transfer_msg = ast_attended_transfer_message_create(0, props->transferer,
1713 props->transferee_bridge, props->transferer, props->target_bridge,
1714 NULL, NULL);
1715
1716 if (!transfer_msg) {
1717 ast_log(LOG_ERROR, "Unable to publish failed transfer from %s\n",
1719 return;
1720 }
1721
1722 transfer_msg->result = AST_BRIDGE_TRANSFER_FAIL;
1724 ao2_cleanup(transfer_msg);
1725}
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1106
void ast_bridge_publish_attended_transfer(struct ast_attended_transfer_message *transfer_msg)
Publish an attended transfer.
struct ast_attended_transfer_message * ast_attended_transfer_message_create(int is_external, struct ast_channel *to_transferee, struct ast_bridge *transferee_bridge, struct ast_channel *to_transfer_target, struct ast_bridge *target_bridge, struct ast_channel *transferee, struct ast_channel *transfer_target)
Create an Attended transfer message to be published.
Message representing attended transfer.
enum ast_transfer_result result

References ao2_cleanup, ast_attended_transfer_message_create(), ast_bridge_publish_attended_transfer(), AST_BRIDGE_TRANSFER_FAIL, ast_channel_name(), ast_log, LOG_ERROR, NULL, ast_attended_transfer_message::result, attended_transfer_properties::target_bridge, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

Referenced by calling_target_exit(), double_checking_exit(), and hesitant_exit().

◆ publish_transfer_success()

static void publish_transfer_success ( struct attended_transfer_properties props,
struct ast_channel transferee_channel,
struct ast_channel target_channel 
)
static

Send a stasis publication for a successful attended transfer.

Definition at line 1661 of file bridge_basic.c.

1663{
1664 struct ast_attended_transfer_message *transfer_msg;
1665
1666 transfer_msg = ast_attended_transfer_message_create(0, props->transferer,
1667 props->transferee_bridge, props->transferer, props->target_bridge,
1668 transferee_channel, target_channel);
1669
1670 if (!transfer_msg) {
1671 ast_log(LOG_ERROR, "Unable to publish successful attended transfer from %s\n",
1673 return;
1674 }
1675
1678 ao2_cleanup(transfer_msg);
1679}
int ast_attended_transfer_message_add_merge(struct ast_attended_transfer_message *transfer_msg, struct ast_bridge *final_bridge)
Add details for a bridge merge to an attended transfer message.

References ao2_cleanup, ast_attended_transfer_message_add_merge(), ast_attended_transfer_message_create(), ast_bridge_publish_attended_transfer(), ast_channel_name(), ast_log, LOG_ERROR, attended_transfer_properties::target_bridge, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

Referenced by blond_enter(), and complete_enter().

◆ publish_transfer_threeway()

static void publish_transfer_threeway ( struct attended_transfer_properties props,
struct ast_channel transferee_channel,
struct ast_channel target_channel 
)
static

Send a stasis publication for an attended transfer that ends in a threeway call.

Definition at line 1684 of file bridge_basic.c.

1686{
1687 struct ast_attended_transfer_message *transfer_msg;
1688
1689 transfer_msg = ast_attended_transfer_message_create(0, props->transferer,
1690 props->transferee_bridge, props->transferer, props->target_bridge,
1691 transferee_channel, target_channel);
1692
1693 if (!transfer_msg) {
1694 ast_log(LOG_ERROR, "Unable to publish successful three-way transfer from %s\n",
1696 return;
1697 }
1698
1700 props->transferee_bridge);
1702 ao2_cleanup(transfer_msg);
1703}
int ast_attended_transfer_message_add_threeway(struct ast_attended_transfer_message *transfer_msg, struct ast_channel *survivor_channel, struct ast_bridge *survivor_bridge)
Add details for an attended transfer that was resolved as a three-way call.

References ao2_cleanup, ast_attended_transfer_message_add_threeway(), ast_attended_transfer_message_create(), ast_bridge_publish_attended_transfer(), ast_channel_name(), ast_log, LOG_ERROR, attended_transfer_properties::target_bridge, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

Referenced by threeway_enter().

◆ rebridge_enter()

static int rebridge_enter ( struct attended_transfer_properties props)
static

◆ recall_callback()

static void recall_callback ( struct ast_dial dial)
static

Dial callback when attempting to recall the original transferer channel.

This is how we can monitor if the recall target has answered or has hung up. If one of the two is detected, then an appropriate stimulus is sent to the attended transfer monitor thread.

Definition at line 2404 of file bridge_basic.c.

2405{
2407
2408 switch (ast_dial_state(dial)) {
2409 default:
2415 /* Failure cases */
2417 break;
2422 /* Don't care about these cases */
2423 break;
2425 /* We struck gold! */
2428 break;
2429 }
2430}
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:1008
@ AST_DIAL_RESULT_FAILED
Definition: dial.h:56
@ AST_DIAL_RESULT_HANGUP
Definition: dial.h:63
@ AST_DIAL_RESULT_INVALID
Definition: dial.h:55
@ AST_DIAL_RESULT_ANSWERED
Definition: dial.h:61
@ AST_DIAL_RESULT_TIMEOUT
Definition: dial.h:62
@ AST_DIAL_RESULT_TRYING
Definition: dial.h:57
@ AST_DIAL_RESULT_PROGRESS
Definition: dial.h:59
@ AST_DIAL_RESULT_RINGING
Definition: dial.h:58
@ AST_DIAL_RESULT_PROCEEDING
Definition: dial.h:60
@ AST_DIAL_RESULT_UNANSWERED
Definition: dial.h:64
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
Definition: dial.c:989
void * ast_dial_get_user_data(struct ast_dial *dial)
Return the user data on a dial structure.
Definition: dial.c:1279

References ast_dial_answered_steal(), ast_dial_get_user_data(), AST_DIAL_RESULT_ANSWERED, AST_DIAL_RESULT_FAILED, AST_DIAL_RESULT_HANGUP, AST_DIAL_RESULT_INVALID, AST_DIAL_RESULT_PROCEEDING, AST_DIAL_RESULT_PROGRESS, AST_DIAL_RESULT_RINGING, AST_DIAL_RESULT_TIMEOUT, AST_DIAL_RESULT_TRYING, AST_DIAL_RESULT_UNANSWERED, ast_dial_state(), attended_transfer_properties::dial, attended_transfer_properties::recall_target, stimulate_attended_transfer(), STIMULUS_RECALL_TARGET_ANSWER, and STIMULUS_RECALL_TARGET_HANGUP.

Referenced by recalling_enter().

◆ recall_pull()

static void recall_pull ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel,
struct attended_transfer_properties props 
)
static

Definition at line 2953 of file bridge_basic.c.

2954{
2955 if (self == props->target_bridge) {
2956 /* Once we're in the recall superstate, we no longer care about this bridge */
2957 return;
2958 }
2959
2960 if (bridge_channel->chan == props->recall_target) {
2962 return;
2963 }
2964
2965 if (self->num_channels == 0) {
2966 /* Empty bridge means all transferees are gone for sure */
2968 return;
2969 }
2970
2971 if (self->num_channels == 1) {
2972 struct ast_bridge_channel *target_bridge_channel;
2973
2974 if (!props->recall_target) {
2975 /* No recall target means that the pull happened on a transferee. If there's still
2976 * a channel left in the bridge, we don't need to send a stimulus
2977 */
2978 return;
2979 }
2980
2982 target_bridge_channel = ast_channel_get_bridge_channel(props->recall_target);
2984
2985 if (target_bridge_channel) {
2986 if (AST_LIST_FIRST(&self->channels) == target_bridge_channel) {
2988 }
2989 ao2_ref(target_bridge_channel, -1);
2990 }
2991 }
2992}

References ao2_ref, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, AST_LIST_FIRST, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge::num_channels, attended_transfer_properties::recall_target, stimulate_attended_transfer(), STIMULUS_RECALL_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, and attended_transfer_properties::target_bridge.

Referenced by bridge_personality_atxfer_pull().

◆ recalling_enter()

static int recalling_enter ( struct attended_transfer_properties props)
static

Definition at line 2469 of file bridge_basic.c.

2470{
2472 struct ast_channel *recall;
2473
2474 if (!cap) {
2475 return -1;
2476 }
2477
2479
2480 /* When we dial the transfer target, since we are communicating
2481 * with a local channel, we can place the local channel in a bridge
2482 * and then call out to it. When recalling the transferer, though, we
2483 * have to use the dialing API because the channel is not local.
2484 */
2485 props->dial = ast_dial_create();
2486 if (!props->dial) {
2487 return -1;
2488 }
2489
2490 if (ast_dial_append(props->dial, props->transferer_type, props->transferer_addr, NULL)) {
2491 return -1;
2492 }
2493
2494 if (ast_dial_prerun(props->dial, NULL, cap)) {
2495 return -1;
2496 }
2497
2498 /*
2499 * Setup callid, variables, datastores, accountcode, peeraccount,
2500 * COLP, and CLID on the recalled transferrer.
2501 */
2502 recall = ast_dial_get_channel(props->dial, 0);
2503 if (!recall) {
2504 return -1;
2505 }
2506 ast_channel_lock_both(recall, props->transferer);
2507
2511 &props->original_transferer_colp);
2512
2514 ast_channel_unlock(recall);
2516
2518
2519 ao2_ref(props, +1);
2520 ast_dial_set_user_data(props->dial, props);
2521
2522 if (ast_dial_run(props->dial, NULL, 1) == AST_DIAL_RESULT_FAILED) {
2523 ao2_ref(props, -1);
2524 return -1;
2525 }
2526
2528 return 0;
2529}
static void bridge_ringing(struct ast_bridge *bridge)
Helper method to send a ringing indication to all channels in a bridge.
static void recall_callback(struct ast_dial *dial)
Dial callback when attempting to recall the original transferer channel.
static void common_recall_channel_setup(struct ast_channel *recall, struct ast_channel *transferer)
void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party_caller *src)
Copy the source caller information to the destination caller.
Definition: channel.c:1986
void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
Set a callback for state changes.
Definition: dial.c:1269
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
Definition: dial.c:280
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:223
void ast_dial_set_user_data(struct ast_dial *dial, void *user_data)
Set user data on a dial structure.
Definition: dial.c:1274
int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_format_cap *cap)
Request all appended channels, but do not dial.
Definition: dial.c:431
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
Definition: dial.c:935
struct ast_channel * ast_dial_get_channel(struct ast_dial *dial, int num)
Get the dialing channel, if prerun has been executed.
Definition: dial.c:1258
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
const ast_string_field transferer_type
const ast_string_field transferer_addr
#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_cleanup, ao2_ref, ast_channel_caller(), ast_channel_connected(), ast_channel_lock_both, ast_channel_unlock, ast_dial_append(), ast_dial_create(), ast_dial_get_channel(), ast_dial_prerun(), AST_DIAL_RESULT_FAILED, ast_dial_run(), ast_dial_set_state_callback(), ast_dial_set_user_data(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_party_caller_copy(), ast_party_connected_line_copy(), bridge_ringing(), common_recall_channel_setup(), attended_transfer_properties::dial, NULL, attended_transfer_properties::original_transferer_colp, RAII_VAR, recall_callback(), attended_transfer_properties::transferee_bridge, attended_transfer_properties::transferer, attended_transfer_properties::transferer_addr, and attended_transfer_properties::transferer_type.

◆ recalling_exit()

static enum attended_transfer_state recalling_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 2531 of file bridge_basic.c.

2533{
2534 /* No matter what the outcome was, we need to kill off the dial */
2535 ast_dial_join(props->dial);
2536 ast_dial_destroy(props->dial);
2537 props->dial = NULL;
2538 /* This reference is the one we incremented for the dial state callback (recall_callback) to use */
2539 ao2_ref(props, -1);
2540
2541 switch (stimulus) {
2543 return TRANSFER_FAIL;
2544 case STIMULUS_TIMEOUT:
2546 ++props->retry_attempts;
2547 if (props->retry_attempts >= props->atxfercallbackretries) {
2548 return TRANSFER_FAIL;
2549 }
2550 if (props->atxferloopdelay) {
2552 }
2553 return TRANSFER_RETRANSFER;
2555 /* Setting this datastore up will allow the transferer to have all of his
2556 * call features set up automatically when the bridge changes back to a
2557 * normal personality
2558 */
2563 ast_hangup(props->recall_target);
2565 return TRANSFER_FAIL;
2566 }
2567 return TRANSFER_RESUME;
2568 case STIMULUS_NONE:
2576 default:
2577 ast_log(LOG_WARNING, "Unexpected stimulus '%s' received in attended transfer state '%s'\n",
2578 stimulus_strs[stimulus], state_properties[props->state].state_name);
2579 return props->state;
2580 }
2581}
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1017
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091

References ao2_ref, ast_bridge_features_ds_set(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_channel_ref, ast_channel_unref, ast_dial_destroy(), ast_dial_join(), ast_hangup(), ast_log, attended_transfer_properties::atxfercallbackretries, attended_transfer_properties::atxferloopdelay, attended_transfer_properties::dial, LOG_WARNING, NULL, attended_transfer_properties::recall_target, attended_transfer_properties::retry_attempts, attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, STIMULUS_DTMF_ATXFER_ABORT, STIMULUS_DTMF_ATXFER_COMPLETE, STIMULUS_DTMF_ATXFER_SWAP, STIMULUS_DTMF_ATXFER_THREEWAY, STIMULUS_NONE, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_RECALL_TARGET_HANGUP, stimulus_strs, STIMULUS_TIMEOUT, STIMULUS_TRANSFER_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, STIMULUS_TRANSFERER_HANGUP, TRANSFER_FAIL, TRANSFER_RESUME, TRANSFER_RETRANSFER, TRANSFER_WAIT_TO_RETRANSFER, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer_features.

◆ remove_attended_transfer_stimulus()

static void remove_attended_transfer_stimulus ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 1566 of file bridge_basic.c.

1568{
1569 struct stimulus_list *list;
1570
1571 ao2_lock(props);
1573 if (list->stimulus == stimulus) {
1575 ast_free(list);
1576 break;
1577 }
1578 }
1580 ao2_unlock(props);
1581}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
enum attended_transfer_stimulus stimulus

References ao2_lock, ao2_unlock, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, stimulus_list::next, stimulus_list::stimulus, and attended_transfer_properties::stimulus_queue.

Referenced by blond_nonfinal_exit().

◆ remove_hooks_on_personality_change()

static void remove_hooks_on_personality_change ( struct ast_bridge bridge)
static

Remove appropriate hooks when basic bridge personality changes.

Hooks that have the AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE flag set will be removed from all bridge channels in the bridge.

Parameters
bridgeBasic bridge undergoing personality change

Definition at line 719 of file bridge_basic.c.

720{
721 struct ast_bridge_channel *iter;
722
726 }
727}
void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags flags)
Remove marked bridge channel feature hooks.
Definition: bridge.c:3501
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.

References ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE, AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge::channels, ast_bridge_channel::features, lock, and SCOPED_LOCK.

Referenced by bridge_basic_change_personality().

◆ resume_enter()

static int resume_enter ( struct attended_transfer_properties props)
static

Definition at line 2203 of file bridge_basic.c.

2204{
2205 return 0;
2206}

◆ retransfer_enter()

static int retransfer_enter ( struct attended_transfer_properties props)
static

Definition at line 2617 of file bridge_basic.c.

2618{
2620 char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
2621 int cause;
2622
2623 if (!cap) {
2624 return -1;
2625 }
2626
2627 snprintf(destination, sizeof(destination), "%s@%s", props->exten, props->context);
2628
2630
2631 /* Get a channel that is the destination we wish to call */
2632 props->recall_target = ast_request("Local", cap, NULL, NULL, destination, &cause);
2633 if (!props->recall_target) {
2634 ast_log(LOG_ERROR, "Unable to request outbound channel for recall target\n");
2635 return -1;
2636 }
2637
2638 if (attach_framehook(props, props->recall_target)) {
2639 ast_log(LOG_ERROR, "Unable to attach framehook to recall target\n");
2640 ast_hangup(props->recall_target);
2641 props->recall_target = NULL;
2642 return -1;
2643 }
2644
2645 /*
2646 * Setup callid, variables, datastores, accountcode, peeraccount,
2647 * and COLP on the recalled transfer target.
2648 */
2650
2652 &props->original_transferer_colp);
2654
2658
2659 if (ast_call(props->recall_target, destination, 0)) {
2660 ast_log(LOG_ERROR, "Unable to place outbound call to recall target\n");
2661 ast_hangup(props->recall_target);
2662 props->recall_target = NULL;
2663 return -1;
2664 }
2665
2669 ast_log(LOG_ERROR, "Unable to place recall target into bridge\n");
2670 ast_hangup(props->recall_target);
2672 return -1;
2673 }
2674
2675 return 0;
2676}
void ast_party_id_reset(struct ast_party_id *id)
Destroy and initialize the given party id structure.
Definition: channel.c:1896
struct ast_party_id priv
Private connected party ID.
Definition: channel.h:468

References ao2_cleanup, ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_call(), ast_channel_connected(), ast_channel_lock_both, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_hangup(), ast_log, AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_party_connected_line_copy(), ast_party_id_reset(), ast_request(), attach_framehook(), common_recall_channel_setup(), attended_transfer_properties::context, attended_transfer_properties::exten, LOG_ERROR, NULL, attended_transfer_properties::original_transferer_colp, ast_party_connected_line::priv, RAII_VAR, attended_transfer_properties::recall_target, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

◆ retransfer_exit()

static enum attended_transfer_state retransfer_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 2678 of file bridge_basic.c.

2680{
2681 switch (stimulus) {
2683 return TRANSFER_FAIL;
2684 case STIMULUS_TIMEOUT:
2688 if (props->atxferloopdelay) {
2690 }
2691 return TRANSFER_RECALLING;
2693 return TRANSFER_RESUME;
2694 case STIMULUS_NONE:
2702 default:
2703 ast_log(LOG_WARNING, "Unexpected stimulus '%s' received in attended transfer state '%s'\n",
2704 stimulus_strs[stimulus], state_properties[props->state].state_name);
2705 return props->state;
2706 }
2707}

References ast_channel_unref, ast_log, ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, attended_transfer_properties::atxferloopdelay, LOG_WARNING, attended_transfer_properties::recall_target, attended_transfer_properties::state, attended_transfer_state_properties::state_name, state_properties, STIMULUS_DTMF_ATXFER_ABORT, STIMULUS_DTMF_ATXFER_COMPLETE, STIMULUS_DTMF_ATXFER_SWAP, STIMULUS_DTMF_ATXFER_THREEWAY, STIMULUS_NONE, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_RECALL_TARGET_HANGUP, stimulus_strs, STIMULUS_TIMEOUT, STIMULUS_TRANSFER_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, STIMULUS_TRANSFERER_HANGUP, TRANSFER_FAIL, TRANSFER_RECALLING, TRANSFER_RESUME, and TRANSFER_WAIT_TO_RECALL.

◆ ringing()

static void ringing ( struct ast_channel chan)
static

Helper method to send a ringing indication to a channel in a bridge.

Definition at line 1830 of file bridge_basic.c.

1831{
1832 struct ast_bridge_channel *bridge_channel;
1833
1835 bridge_channel = ast_channel_get_bridge_channel(chan);
1837
1838 if (bridge_channel) {
1840 ao2_ref(bridge_channel, -1);
1841 }
1842}
int ast_bridge_channel_write_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
Write a control frame into the bridge with data.

References ao2_ref, ast_bridge_channel_write_control_data(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_RINGING, ast_bridge_channel::chan, and NULL.

Referenced by blond_enter(), bridge_ringing(), queue_exec(), say_periodic_announcement(), say_position(), try_calling(), and wait_our_turn().

◆ set_feature_flag_from_char()

static int set_feature_flag_from_char ( struct ast_flags feature_flags,
char  feature 
)
static

Definition at line 98 of file bridge_basic.c.

99{
100 switch (feature) {
101 case 'T':
102 ast_set_flag(feature_flags, AST_FEATURE_REDIRECT);
103 return 0;
104 case 'K':
105 ast_set_flag(feature_flags, AST_FEATURE_PARKCALL);
106 return 0;
107 case 'H':
108 ast_set_flag(feature_flags, AST_FEATURE_DISCONNECT);
109 return 0;
110 case 'W':
111 ast_set_flag(feature_flags, AST_FEATURE_AUTOMON);
112 return 0;
113 case 'X':
114 ast_set_flag(feature_flags, AST_FEATURE_AUTOMIXMON);
115 return 0;
116 default:
117 return -1;
118 }
119}

References AST_FEATURE_AUTOMIXMON, AST_FEATURE_AUTOMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, and ast_set_flag.

Referenced by build_dtmf_features().

◆ setup_bridge_features_builtin()

static int setup_bridge_features_builtin ( struct ast_bridge_features features,
struct ast_channel chan 
)
static

Definition at line 400 of file bridge_basic.c.

401{
402 struct ast_flags *flags;
403 int res;
404
405 ast_channel_lock(chan);
407 ast_channel_unlock(chan);
408 if (!flags) {
409 return 0;
410 }
411
412 res = 0;
418
419 return res ? -1 : 0;
420}
static int builtin_features_helper(struct ast_bridge_features *features, struct ast_channel *chan, struct ast_flags *flags, unsigned int feature_flag, const char *feature_name, enum ast_bridge_builtin_feature feature_bridge)
Definition: bridge_basic.c:368
@ AST_BRIDGE_BUILTIN_AUTOMIXMON
@ AST_BRIDGE_BUILTIN_HANGUP
@ AST_BRIDGE_BUILTIN_PARKCALL

References AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, AST_BRIDGE_BUILTIN_AUTOMIXMON, AST_BRIDGE_BUILTIN_BLINDTRANSFER, AST_BRIDGE_BUILTIN_HANGUP, AST_BRIDGE_BUILTIN_PARKCALL, ast_bridge_features_ds_get(), ast_channel_lock, ast_channel_unlock, AST_FEATURE_AUTOMIXMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, builtin_features_helper(), and ast_flags::flags.

Referenced by bridge_basic_setup_features().

◆ setup_bridge_features_dynamic()

static int setup_bridge_features_dynamic ( struct ast_bridge_features features,
struct ast_channel chan 
)
static

Definition at line 604 of file bridge_basic.c.

605{
606 struct ao2_container *applicationmap;
607 int res = 0;
608
609 ast_channel_lock(chan);
610 applicationmap = ast_get_chan_applicationmap(chan);
611 ast_channel_unlock(chan);
612 if (applicationmap) {
613 ao2_callback_data(applicationmap, 0, setup_dynamic_feature, features, &res);
614 ao2_ref(applicationmap, -1);
615 }
616
617 return res;
618}
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
static int setup_dynamic_feature(void *obj, void *arg, void *data, int flags)
Definition: bridge_basic.c:580
struct ao2_container * ast_get_chan_applicationmap(struct ast_channel *chan)
Get the applicationmap for a given channel.
Generic container type.

References ao2_callback_data, ao2_ref, ast_channel_lock, ast_channel_unlock, ast_get_chan_applicationmap(), and setup_dynamic_feature().

Referenced by bridge_basic_setup_features().

◆ setup_dynamic_feature()

static int setup_dynamic_feature ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 580 of file bridge_basic.c.

581{
582 struct ast_applicationmap_item *item = obj;
583 struct ast_bridge_features *features = arg;
584 int *res = data;
585
586 *res |= dynamic_dtmf_hook_add(features,
588 item->dtmf, item->name, item->app, item->app_data, item->moh_class);
589
590 return 0;
591}
static int dynamic_dtmf_hook_add(struct ast_bridge_features *features, unsigned int flags, const char *dtmf, const char *feature_name, const char *app_name, const char *app_args, const char *moh_class)
Definition: bridge_basic.c:543
@ AST_FEATURE_FLAG_ONSELF
Definition: features.h:36
const char * name
An applicationmap configuration item.
Structure that contains features information.
static struct aco_type item
Definition: test_config.c:1463

References AST_FEATURE_FLAG_ONPEER, AST_FEATURE_FLAG_ONSELF, dynamic_dtmf_hook_add(), item, and aco_type::name.

Referenced by setup_bridge_features_dynamic().

◆ stimulate_attended_transfer()

static void stimulate_attended_transfer ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Definition at line 1548 of file bridge_basic.c.

1550{
1551 struct stimulus_list *list;
1552
1553 list = ast_calloc(1, sizeof(*list));
1554 if (!list) {
1555 ast_log(LOG_ERROR, "Unable to push event to attended transfer queue. Expect transfer to fail\n");
1556 return;
1557 }
1558
1559 list->stimulus = stimulus;
1560 ao2_lock(props);
1562 ast_cond_signal(&props->cond);
1563 ao2_unlock(props);
1564}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define ast_cond_signal(cond)
Definition: lock.h:203

References ao2_lock, ao2_unlock, ast_calloc, ast_cond_signal, AST_LIST_INSERT_TAIL, ast_log, attended_transfer_properties::cond, LOG_ERROR, stimulus_list::next, stimulus_list::stimulus, and attended_transfer_properties::stimulus_queue.

Referenced by atxfer_abort(), atxfer_complete(), atxfer_swap(), atxfer_threeway(), atxfer_transferer_hangup(), recall_callback(), recall_pull(), transfer_pull(), and transfer_target_framehook_cb().

◆ stream_failsound()

static void stream_failsound ( struct ast_channel chan)
static

Helper method to stream a fail sound on a channel.

Parameters
chanThe channel to stream the fail sound to

Definition at line 1771 of file bridge_basic.c.

1772{
1773 char *sound;
1774
1775 ast_channel_lock(chan);
1777 ast_channel_unlock(chan);
1778
1779 if (sound) {
1780 ast_stream_and_wait(chan, sound, AST_DIGIT_NONE);
1781 ast_free(sound);
1782 }
1783}

References ast_channel_lock, ast_channel_unlock, AST_DIGIT_NONE, ast_free, ast_get_chan_features_xferfailsound(), ast_stream_and_wait(), and ast_bridge_channel::chan.

Referenced by feature_attended_transfer().

◆ threeway_enter()

static int threeway_enter ( struct attended_transfer_properties props)
static

Definition at line 2208 of file bridge_basic.c.

2209{
2210 struct ast_channel *transferee_channel;
2211 struct ast_channel *target_channel;
2212
2214 &transferee_channel, &target_channel);
2216 play_sound(props->transfer_target, props->xfersound);
2217 play_sound(props->transferer, props->xfersound);
2218 publish_transfer_threeway(props, transferee_channel, target_channel);
2219
2220 ast_channel_cleanup(transferee_channel);
2221 ast_channel_cleanup(target_channel);
2222 return 0;
2223}
static void publish_transfer_threeway(struct attended_transfer_properties *props, struct ast_channel *transferee_channel, struct ast_channel *target_channel)
Send a stasis publication for an attended transfer that ends in a threeway call.

References ast_channel_cleanup, bridge_merge(), get_transfer_parties(), NULL, play_sound(), publish_transfer_threeway(), attended_transfer_properties::target_bridge, attended_transfer_properties::transfer_target, attended_transfer_properties::transferee_bridge, attended_transfer_properties::transferer, and attended_transfer_properties::xfersound.

◆ transfer_pull()

static void transfer_pull ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel,
struct attended_transfer_properties props 
)
static

Definition at line 2915 of file bridge_basic.c.

2916{
2917 if (self->num_channels > 1 || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2918 return;
2919 }
2920
2921 if (self->num_channels == 1) {
2922 struct ast_bridge_channel *transferer_bridge_channel;
2923 int not_transferer;
2924
2926 transferer_bridge_channel = ast_channel_get_bridge_channel(props->transferer);
2928
2929 if (!transferer_bridge_channel) {
2930 return;
2931 }
2932
2933 not_transferer = AST_LIST_FIRST(&self->channels) != transferer_bridge_channel;
2934 ao2_ref(transferer_bridge_channel, -1);
2935 if (not_transferer) {
2936 return;
2937 }
2938 }
2939
2940 /* Reaching this point means that either
2941 * 1) The bridge has no channels in it
2942 * 2) The bridge has one channel, and it's the transferer
2943 * In either case, it indicates that the non-transferer parties
2944 * are no longer in the bridge.
2945 */
2946 if (self == props->transferee_bridge) {
2948 } else {
2950 }
2951}

References ao2_ref, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, AST_LIST_FIRST, BRIDGE_CHANNEL_STATE_WAIT, ast_bridge::channels, ast_bridge::num_channels, ast_bridge_channel::state, stimulate_attended_transfer(), STIMULUS_TRANSFER_TARGET_HANGUP, STIMULUS_TRANSFEREE_HANGUP, attended_transfer_properties::transferee_bridge, and attended_transfer_properties::transferer.

Referenced by bridge_personality_atxfer_pull().

◆ transfer_target_framehook_cb()

static struct ast_frame * transfer_target_framehook_cb ( struct ast_channel chan,
struct ast_frame frame,
enum ast_framehook_event  event,
void *  data 
)
static

Frame hook for transfer target channel.

This is used to determine if the transfer target or recall target has answered the outgoing call.

When an answer is detected, a stimulus is sent to the attended transfer monitor thread to indicate that the transfer target or recall target has answered.

Parameters
chanThe channel the framehook is attached to.
frameThe frame being read or written.
eventWhat is being done with the frame.
dataThe attended transfer properties.

Definition at line 2834 of file bridge_basic.c.

2836{
2837 struct attended_transfer_properties *props = data;
2838
2840 frame && frame->frametype == AST_FRAME_CONTROL &&
2842 !ast_check_hangup(chan)) {
2843
2844 ast_debug(1, "Detected an answer for recall attempt on attended transfer %p\n", props);
2845 if (props->superstate == SUPERSTATE_TRANSFER) {
2847 } else {
2849 }
2851 props->target_framehook_id = -1;
2852 }
2853
2854 return frame;
2855}
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
@ AST_FRAMEHOOK_EVENT_READ
Definition: framehook.h:152
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
@ AST_CONTROL_ANSWER
struct ast_frame_subclass subclass
enum ast_frame_type frametype
Definition: astman.c:222

References ast_check_hangup(), AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_framehook_detach(), AST_FRAMEHOOK_EVENT_READ, ast_frame::frametype, ast_frame_subclass::integer, stimulate_attended_transfer(), STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_ANSWER, ast_frame::subclass, attended_transfer_properties::superstate, SUPERSTATE_TRANSFER, and attended_transfer_properties::target_framehook_id.

Referenced by attach_framehook().

◆ transfer_target_framehook_consume()

static int transfer_target_framehook_consume ( void *  data,
enum ast_frame_type  type 
)
static

Callback function which informs upstream if we are consuming a frame of a specific type.

Definition at line 2858 of file bridge_basic.c.

2859{
2860 return (type == AST_FRAME_CONTROL ? 1 : 0);
2861}

References AST_FRAME_CONTROL, and type.

Referenced by attach_framehook().

◆ transfer_target_framehook_destroy_cb()

static void transfer_target_framehook_destroy_cb ( void *  data)
static

Definition at line 2863 of file bridge_basic.c.

2864{
2865 struct attended_transfer_properties *props = data;
2866 ao2_cleanup(props);
2867}

References ao2_cleanup.

Referenced by attach_framehook().

◆ unhold()

static void unhold ( struct ast_channel chan)
static

Helper method to take a channel in a bridge off hold.

Definition at line 1809 of file bridge_basic.c.

1810{
1811 struct ast_bridge_channel *bridge_channel;
1812
1813 if (!chan) {
1814 return;
1815 }
1816
1818 bridge_channel = ast_channel_get_bridge_channel(chan);
1820
1821 if (bridge_channel) {
1822 ast_bridge_channel_write_unhold(bridge_channel);
1823 ao2_ref(bridge_channel, -1);
1824 }
1825}

References ao2_ref, ast_bridge_channel_write_unhold(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, and ast_bridge_channel::chan.

Referenced by bridge_unhold(), consulting_exit(), double_checking_exit(), hesitant_enter(), and rebridge_enter().

◆ wait_for_stimulus()

static enum attended_transfer_stimulus wait_for_stimulus ( struct attended_transfer_properties props)
static

Definition at line 3009 of file bridge_basic.c.

3010{
3011 enum attended_transfer_stimulus stimulus;
3012 struct stimulus_list *list;
3014
3015 while (!(list = AST_LIST_REMOVE_HEAD(&props->stimulus_queue, next))) {
3017 ast_cond_wait(&props->cond, lock);
3018 } else {
3019 struct timeval relative_timeout = { 0, };
3020 struct timeval absolute_timeout;
3021 struct timespec timeout_arg;
3022
3024 props->start = ast_tvnow();
3025 }
3026
3028 relative_timeout.tv_sec = props->atxferloopdelay;
3029 } else {
3030 /* Implied TRANSFER_STATE_FLAG_TIMER_ATXFER_NO_ANSWER */
3031 relative_timeout.tv_sec = props->atxfernoanswertimeout;
3032 }
3033
3034 absolute_timeout = ast_tvadd(props->start, relative_timeout);
3035 timeout_arg.tv_sec = absolute_timeout.tv_sec;
3036 timeout_arg.tv_nsec = absolute_timeout.tv_usec * 1000;
3037
3038 if (ast_cond_timedwait(&props->cond, lock, &timeout_arg) == ETIMEDOUT) {
3039 return STIMULUS_TIMEOUT;
3040 }
3041 }
3042 }
3043 stimulus = list->stimulus;
3044 ast_free(list);
3045 return stimulus;
3046}
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:589
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ao2_object_get_lockaddr(), ast_cond_timedwait, ast_cond_wait, ast_free, AST_LIST_REMOVE_HEAD, ast_tvadd(), ast_tvnow(), attended_transfer_properties::atxferloopdelay, attended_transfer_properties::atxfernoanswertimeout, attended_transfer_properties::cond, attended_transfer_state_properties::flags, lock, stimulus_list::next, SCOPED_MUTEX, attended_transfer_properties::start, attended_transfer_properties::state, state_properties, stimulus_list::stimulus, attended_transfer_properties::stimulus_queue, STIMULUS_TIMEOUT, TRANSFER_STATE_FLAG_TIMED, TRANSFER_STATE_FLAG_TIMER_LOOP_DELAY, and TRANSFER_STATE_FLAG_TIMER_RESET.

Referenced by attended_transfer_monitor_thread().

◆ wait_to_recall_enter()

static int wait_to_recall_enter ( struct attended_transfer_properties props)
static

Definition at line 2709 of file bridge_basic.c.

2710{
2712 return 0;
2713}
static void bridge_hold(struct ast_bridge *bridge)
Helper method to send a hold frame to all channels in a bridge.

References bridge_hold(), and attended_transfer_properties::transferee_bridge.

◆ wait_to_recall_exit()

static enum attended_transfer_state wait_to_recall_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

◆ wait_to_retransfer_enter()

static int wait_to_retransfer_enter ( struct attended_transfer_properties props)
static

Definition at line 2583 of file bridge_basic.c.

2584{
2586 return 0;
2587}

References bridge_hold(), and attended_transfer_properties::transferee_bridge.

◆ wait_to_retransfer_exit()

static enum attended_transfer_state wait_to_retransfer_exit ( struct attended_transfer_properties props,
enum attended_transfer_stimulus  stimulus 
)
static

Variable Documentation

◆ ast_bridge_basic_v_table

struct ast_bridge_methods ast_bridge_basic_v_table

Bridge basic class virtual method table.

Definition at line 3564 of file bridge_basic.c.

Referenced by ast_bridge_basic_new(), and ast_bridging_init_basic().

◆ dtmf_features_info

const struct ast_datastore_info dtmf_features_info
static
Initial value:
= {
.type = "bridge-dtmf-features",
.destroy = ast_free_ptr,
}

Definition at line 82 of file bridge_basic.c.

Referenced by ast_bridge_features_ds_get(), and bridge_features_ds_set_full().

◆ personality_atxfer_v_table

struct ast_bridge_methods personality_atxfer_v_table

Definition at line 3566 of file bridge_basic.c.

Referenced by ast_bridging_init_basic(), and init_details().

◆ personality_normal_v_table

struct ast_bridge_methods personality_normal_v_table

Definition at line 3565 of file bridge_basic.c.

Referenced by ast_bridging_init_basic(), and init_details().

◆ state_properties

const struct attended_transfer_state_properties state_properties[]
static

◆ stimulus_strs

const char* stimulus_strs[]