Asterisk - The Open Source Telephony Project  21.4.1
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"

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.
 
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.
 
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.
 
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.
 
static void bridge_unhold (struct ast_bridge *bridge)
 Helper method to send an unhold frame to all channels in a bridge.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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 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.
 
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.
 
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.
 
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.
 
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.
 
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

#define NORMAL_FLAGS

Enumeration Type Documentation

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  */
1229  TRANSFER_FAIL,
1230 };
Rebridge state.
Definition: bridge_basic.c:869
Resume state.
Definition: bridge_basic.c:902
Complete state.
Wait to Retransfer state.
Fail state.
Consulting state.
Definition: bridge_basic.c:956
Retransfer state.
Double-checking state.
Definition: bridge_basic.c:986
Calling Target state.
Definition: bridge_basic.c:807
Wait to recall state.
Blond non-final state.
Recalling state.
Hesitant state.
Definition: bridge_basic.c:841
Blond state.
Threeway state.
Definition: bridge_basic.c:928

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 1955 of file bridge_basic.c.

1955  {
1956  /*! This state requires that the timer be reset when entering the state */
1958  /*! This state's timer uses atxferloopdelay */
1960  /*! This state's timer uses atxfernoanswertimeout */
1962  /*! This state has a time limit associated with it */
1965  /*! This state does not transition to any other states */
1966  TRANSFER_STATE_FLAG_TERMINAL = (1 << 3),
1967 };

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. */
1237  STIMULUS_NONE,
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 };

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 };
Recall superstate.
Definition: bridge_basic.c:767
Transfer superstate.
Definition: bridge_basic.c:752
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 };

Function Documentation

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:

1 struct ast_bridge *bridge;
2 bridge = ast_bridge_basic_new();

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 3661 of file bridge_basic.c.

References ast_bridge_basic_v_table, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_CAPABILITY_NATIVE, bridge_base_init(), and bridge_register().

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

3662 {
3663  struct ast_bridge *bridge;
3664 
3665  bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_basic_v_table);
3666  bridge = bridge_base_init(bridge,
3668  | AST_BRIDGE_CAPABILITY_MULTIMIX, NORMAL_FLAGS, NULL, NULL, NULL);
3669  bridge = bridge_basic_personality_alloc(bridge);
3670  bridge = bridge_register(bridge);
3671  return bridge;
3672 }
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
Structure that contains information about a bridge.
Definition: bridge.h:349
struct ast_bridge_methods ast_bridge_basic_v_table
Bridge basic class virtual method table.
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 3674 of file bridge_basic.c.

References ast_bridge_lock, ast_bridge_unlock, 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().

3675 {
3677  struct bridge_basic_personality *personality = bridge->personality;
3678 
3679  personality->details[personality->current].bridge_flags |= flags;
3680  ast_set_flag(&bridge->feature_flags, flags);
3681 }
struct ast_flags feature_flags
Definition: bridge.h:369
unsigned int bridge_flags
Definition: bridge_basic.c:317
enum bridge_basic_personality_type current
Definition: bridge_basic.c:329
void * personality
Definition: bridge.h:353
ast_mutex_t lock
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:583
structure that organizes different personalities for basic bridges.
Definition: bridge_basic.c:327
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
struct personality_details details[BRIDGE_BASIC_PERSONALITY_END]
Definition: bridge_basic.c:331
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 }
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.

References ast_channel_datastore_find(), and ast_datastore::data.

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

269 {
270  struct ast_datastore *datastore;
271 
272  datastore = ast_channel_datastore_find(chan, &dtmf_features_info, NULL);
273  if (!datastore) {
274  return NULL;
275  }
276  return datastore->data;
277 }
Structure for a data store object.
Definition: datastore.h:64
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
void * data
Definition: datastore.h:66
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.

References ast_bridge_features_ds_get().

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 }
struct ast_flags * ast_bridge_features_ds_get(struct ast_channel *chan)
Get DTMF feature flags from the channel.
Definition: bridge_basic.c:268
Structure used to handle boolean flags.
Definition: utils.h:199
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.

Referenced by ast_bridge_features_ds_set_string(), and parked_call_retrieve_enable_features().

259 {
260  return bridge_features_ds_set_full(chan, flags, 1);
261 }
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.

References ast_bridge_features_ds_set().

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 }
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
Structure used to handle boolean flags.
Definition: utils.h:199
void ast_bridging_init_basic ( void  )

Initialize the basic bridge class for use by the system.

Definition at line 3683 of file bridge_basic.c.

References ast_bridge_base_v_table, ast_bridge_basic_v_table, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, AST_BRIDGE_BUILTIN_BLINDTRANSFER, ast_bridge_features_register(), ast_bridge_methods::destroy, feature_attended_transfer(), feature_blind_transfer(), ast_bridge_methods::name, ast_bridge_methods::pull, and ast_bridge_methods::push.

Referenced by ast_bridging_init().

3684 {
3685  /* Setup bridge basic subclass v_table. */
3687  ast_bridge_basic_v_table.name = "basic";
3688  ast_bridge_basic_v_table.push = bridge_basic_push;
3689  ast_bridge_basic_v_table.pull = bridge_basic_pull;
3690  ast_bridge_basic_v_table.destroy = bridge_basic_destroy;
3691 
3692  /*
3693  * Personality vtables don't have the same rules as
3694  * normal bridge vtables. These vtable functions are
3695  * used as alterations to the ast_bridge_basic_v_table
3696  * method functionality and are checked for NULL before
3697  * calling.
3698  */
3699  personality_normal_v_table.name = "normal";
3700  personality_normal_v_table.push = bridge_personality_normal_push;
3701 
3702  personality_atxfer_v_table.name = "attended transfer";
3703  personality_atxfer_v_table.push = bridge_personality_atxfer_push;
3704  personality_atxfer_v_table.pull = bridge_personality_atxfer_pull;
3705 
3708 }
const char * name
Definition: bridge.h:259
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:923
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
struct ast_bridge_methods ast_bridge_basic_v_table
Bridge basic class virtual method table.
static int feature_blind_transfer(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Internal built in feature for blind transfers.
ast_bridge_pull_channel_fn pull
Definition: bridge.h:267
ast_bridge_destructor_fn destroy
Definition: bridge.h:261
ast_bridge_push_channel_fn push
Definition: bridge.h:265
static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Internal built in feature for attended transfers.
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 3064 of file bridge_basic.c.

References ast_callid_threadassoc_add(), ast_callid_threadassoc_remove(), ast_debug, attended_transfer_properties_shutdown(), attended_transfer_state_properties::enter, attended_transfer_state_properties::exit, attended_transfer_state_properties::flags, attended_transfer_properties::state, attended_transfer_state_properties::state_name, TRANSFER_STATE_FLAG_TERMINAL, and attended_transfer_properties::transferer.

Referenced by feature_attended_transfer().

3065 {
3066  struct attended_transfer_properties *props = data;
3067  ast_callid callid;
3068 
3069  /*
3070  * Set thread callid to the transferer's callid because we
3071  * are doing all this on that channel's behalf.
3072  */
3073  ast_channel_lock(props->transferer);
3074  callid = ast_channel_callid(props->transferer);
3075  ast_channel_unlock(props->transferer);
3076  if (callid) {
3078  }
3079 
3080  for (;;) {
3081  enum attended_transfer_stimulus stimulus;
3082 
3083  ast_debug(1, "About to enter state %s for attended transfer %p\n", state_properties[props->state].state_name, props);
3084 
3085  if (state_properties[props->state].enter &&
3086  state_properties[props->state].enter(props)) {
3087  ast_log(LOG_ERROR, "State %s enter function returned an error for attended transfer %p\n",
3088  state_properties[props->state].state_name, props);
3089  break;
3090  }
3091 
3092  if (state_properties[props->state].flags & TRANSFER_STATE_FLAG_TERMINAL) {
3093  ast_debug(1, "State %s is a terminal state. Ending attended transfer %p\n",
3094  state_properties[props->state].state_name, props);
3095  break;
3096  }
3097 
3098  stimulus = wait_for_stimulus(props);
3099 
3100  ast_debug(1, "Received stimulus %s on attended transfer %p\n", stimulus_strs[stimulus], props);
3101 
3102  ast_assert(state_properties[props->state].exit != NULL);
3103 
3104  props->state = state_properties[props->state].exit(props, stimulus);
3105 
3106  ast_debug(1, "Told to enter state %s exit on attended transfer %p\n", state_properties[props->state].state_name, props);
3107  }
3108 
3110 
3111  if (callid) {
3113  }
3114 
3115  return NULL;
3116 }
enum attended_transfer_state(* exit)(struct attended_transfer_properties *props, enum attended_transfer_stimulus stimulus)
static void attended_transfer_properties_shutdown(struct attended_transfer_properties *props)
Initiate shutdown of attended transfer properties.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:2320
const char * stimulus_strs[]
String representations of the various stimuli.
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
Definition: logger.c:2339
enum attended_transfer_state state
#define ast_debug(level,...)
Log a DEBUG message.
attended_transfer_stimulus
Stimuli that can cause transfer state changes.
struct ast_channel * transferer
Collection of data related to an attended transfer attempt.
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.

References ao2_ref, ast_bridge_features_ds_get(), ast_channel_ref, ast_debug, ast_party_connected_line_copy(), ast_strdupa, ast_string_field_init, ast_string_field_set, 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, attended_transfer_properties::original_transferer_colp, attended_transfer_properties::target_framehook_id, attended_transfer_properties::transferer, attended_transfer_properties::transferer_addr, attended_transfer_properties::transferer_features, attended_transfer_properties::transferer_type, ast_features_xfer_config::xfersound, and attended_transfer_properties::xfersound.

Referenced by feature_attended_transfer().

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 
1454  ast_channel_lock(props->transferer);
1455  xfer_cfg = ast_get_chan_features_xfer_config(props->transferer);
1456  if (!xfer_cfg) {
1457  ast_log(LOG_ERROR, "Unable to get transfer configuration from channel %s\n", ast_channel_name(props->transferer));
1458  ast_channel_unlock(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;
1467  props->atxfercallbackretries = xfer_cfg->atxfercallbackretries;
1468  props->atxfernoanswertimeout = xfer_cfg->atxfernoanswertimeout;
1469  props->atxferloopdelay = xfer_cfg->atxferloopdelay;
1470  ast_string_field_set(props, context, get_transfer_context(transferer, context));
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  */
1480  ast_channel_connected(props->transferer));
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");
1486  ast_channel_unlock(props->transferer);
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 
1498  ast_channel_unlock(props->transferer);
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 }
Feature configuration relating to transfers.
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_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#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
struct ast_flags transferer_features
#define ast_debug(level,...)
Log a DEBUG message.
Structure used to handle boolean flags.
Definition: utils.h:199
struct ast_party_connected_line original_transferer_colp
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_channel * transferer
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
Collection of data related to an attended transfer attempt.
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.

References ast_bridge_destroy(), ast_bridge_merge_inhibit(), ast_channel_remove_bridge_role(), ast_debug, bridge_basic_change_personality(), BRIDGE_BASIC_PERSONALITY_NORMAL, clear_stimulus_queue(), 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().

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) {
1535  ast_bridge_destroy(props->target_bridge, 0);
1536  props->target_bridge = NULL;
1537  }
1538 
1539  if (props->transferer) {
1540  ast_channel_remove_bridge_role(props->transferer, AST_TRANSFERER_ROLE_NAME);
1541  }
1542 
1543  clear_stimulus_queue(props);
1544 
1545  ao2_cleanup(props);
1546 }
static void clear_stimulus_queue(struct attended_transfer_properties *props)
Free backlog of stimuli in the queue.
static void bridge_basic_change_personality(struct ast_bridge *bridge, enum bridge_basic_personality_type type, void *user_data)
Change basic bridge personality.
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
struct ast_bridge * transferee_bridge
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
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_bridge * target_bridge
struct ast_channel * transferer
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 2761 of file bridge_basic.c.

References ast_debug, and STIMULUS_DTMF_ATXFER_ABORT.

2762 {
2763  struct attended_transfer_properties *props = hook_pvt;
2764 
2765  ast_debug(1, "Transferer on attended transfer %p pressed abort sequence\n", props);
2766  stimulate_attended_transfer(props, STIMULUS_DTMF_ATXFER_ABORT);
2767  return 0;
2768 }
#define ast_debug(level,...)
Log a DEBUG message.
Collection of data related to an attended transfer attempt.
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 2775 of file bridge_basic.c.

References ast_debug, and STIMULUS_DTMF_ATXFER_COMPLETE.

2776 {
2777  struct attended_transfer_properties *props = hook_pvt;
2778 
2779  ast_debug(1, "Transferer on attended transfer %p pressed complete sequence\n", props);
2780  stimulate_attended_transfer(props, STIMULUS_DTMF_ATXFER_COMPLETE);
2781  return 0;
2782 }
#define ast_debug(level,...)
Log a DEBUG message.
Collection of data related to an attended transfer attempt.
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 2803 of file bridge_basic.c.

References ast_debug, and STIMULUS_DTMF_ATXFER_SWAP.

2804 {
2805  struct attended_transfer_properties *props = hook_pvt;
2806 
2807  ast_debug(1, "Transferer on attended transfer %p pressed swap sequence\n", props);
2808  stimulate_attended_transfer(props, STIMULUS_DTMF_ATXFER_SWAP);
2809  return 0;
2810 }
#define ast_debug(level,...)
Log a DEBUG message.
Collection of data related to an attended transfer attempt.
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 2789 of file bridge_basic.c.

References ast_debug, and STIMULUS_DTMF_ATXFER_THREEWAY.

2790 {
2791  struct attended_transfer_properties *props = hook_pvt;
2792 
2793  ast_debug(1, "Transferer on attended transfer %p pressed threeway sequence\n", props);
2794  stimulate_attended_transfer(props, STIMULUS_DTMF_ATXFER_THREEWAY);
2795  return 0;
2796 }
#define ast_debug(level,...)
Log a DEBUG message.
Collection of data related to an attended transfer attempt.
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 2817 of file bridge_basic.c.

References ast_debug, and STIMULUS_TRANSFERER_HANGUP.

2818 {
2819  struct attended_transfer_properties *props = hook_pvt;
2820 
2821  ast_debug(1, "Transferer on attended transfer %p hung up\n", props);
2822  stimulate_attended_transfer(props, STIMULUS_TRANSFERER_HANGUP);
2823  return 0;
2824 }
#define ast_debug(level,...)
Log a DEBUG message.
Collection of data related to an attended transfer attempt.
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 3574 of file bridge_basic.c.

References ao2_ref, ast_bridge_lock, ast_bridge_unlock, personality_details::bridge_flags, bridge_basic_personality::current, bridge_basic_personality::details, ast_bridge::feature_flags, lock, personality_details::on_personality_change, ast_bridge::personality, personality_details::pvt, remove_hooks_on_personality_change(), and SCOPED_LOCK.

Referenced by attended_transfer_properties_shutdown(), and feature_attended_transfer().

3576 {
3577  struct bridge_basic_personality *personality = bridge->personality;
3579 
3581 
3582  ao2_cleanup(personality->details[personality->current].pvt);
3583  personality->details[personality->current].pvt = NULL;
3584  ast_clear_flag(&bridge->feature_flags, AST_FLAGS_ALL);
3585 
3586  personality->current = type;
3587  if (user_data) {
3588  ao2_ref(user_data, +1);
3589  }
3590  personality->details[personality->current].pvt = user_data;
3591  ast_set_flag(&bridge->feature_flags, personality->details[personality->current].bridge_flags);
3592  if (personality->details[personality->current].on_personality_change) {
3593  personality->details[personality->current].on_personality_change(bridge);
3594  }
3595 }
struct ast_flags feature_flags
Definition: bridge.h:369
unsigned int bridge_flags
Definition: bridge_basic.c:317
void(* on_personality_change)(struct ast_bridge *bridge)
Definition: bridge_basic.c:321
enum bridge_basic_personality_type current
Definition: bridge_basic.c:329
void * personality
Definition: bridge.h:353
ast_mutex_t lock
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:583
static void remove_hooks_on_personality_change(struct ast_bridge *bridge)
Remove appropriate hooks when basic bridge personality changes.
Definition: bridge_basic.c:719
structure that organizes different personalities for basic bridges.
Definition: bridge_basic.c:327
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
struct personality_details details[BRIDGE_BASIC_PERSONALITY_END]
Definition: bridge_basic.c:331
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 3340 of file bridge_basic.c.

References 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_ref, ast_debug, ast_hangup(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_string_field_set, 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, ast_bridge_methods::name, 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().

3341 {
3342  struct ast_bridge_features_attended_transfer *attended_transfer = hook_pvt;
3343  struct attended_transfer_properties *props;
3344  struct ast_bridge *bridge;
3345  char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 1];
3346  char exten[AST_MAX_EXTENSION] = "";
3347  pthread_t thread;
3348 
3349  /* Inhibit the bridge before we do anything else. */
3350  bridge = ast_bridge_channel_merge_inhibit(bridge_channel, +1);
3351 
3352  ast_verb(3, "Channel %s: Started DTMF attended transfer.\n",
3353  ast_channel_name(bridge_channel->chan));
3354 
3355  if (strcmp(bridge->v_table->name, "basic")) {
3356  ast_log(LOG_ERROR, "Channel %s: Attended transfer attempted on unsupported bridge type '%s'.\n",
3357  ast_channel_name(bridge_channel->chan), bridge->v_table->name);
3358  ast_bridge_merge_inhibit(bridge, -1);
3359  ao2_ref(bridge, -1);
3360  return 0;
3361  }
3362 
3363  /* Was the bridge inhibited before we inhibited it? */
3364  if (1 < bridge->inhibit_merge) {
3365  /*
3366  * The peer likely initiated attended transfer at the same time
3367  * and we lost the race.
3368  */
3369  ast_verb(3, "Channel %s: Bridge '%s' does not permit merging at this time.\n",
3370  ast_channel_name(bridge_channel->chan), bridge->uniqueid);
3371  ast_bridge_merge_inhibit(bridge, -1);
3372  ao2_ref(bridge, -1);
3373  return 0;
3374  }
3375 
3376  props = attended_transfer_properties_alloc(bridge_channel->chan,
3377  attended_transfer ? attended_transfer->context : NULL);
3378  if (!props) {
3379  ast_log(LOG_ERROR, "Channel %s: Unable to allocate control structure for performing attended transfer.\n",
3380  ast_channel_name(bridge_channel->chan));
3381  ast_bridge_merge_inhibit(bridge, -1);
3382  ao2_ref(bridge, -1);
3383  return 0;
3384  }
3385 
3386  props->transferee_bridge = bridge;
3387 
3388  if (add_transferer_role(props->transferer, attended_transfer)) {
3389  ast_log(LOG_ERROR, "Channel %s: Unable to set transferrer bridge role.\n",
3390  ast_channel_name(bridge_channel->chan));
3392  return 0;
3393  }
3394 
3395  ast_bridge_channel_write_hold(bridge_channel, NULL);
3396 
3397  /* Grab the extension to transfer to */
3398  if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), props->context)) {
3399  /*
3400  * This is a normal exit for when the user fails
3401  * to specify a valid transfer target. e.g., The user
3402  * hungup, didn't dial any digits, or dialed an invalid
3403  * extension.
3404  */
3405  ast_verb(3, "Channel %s: Unable to acquire target extension for attended transfer.\n",
3406  ast_channel_name(bridge_channel->chan));
3407  ast_bridge_channel_write_unhold(bridge_channel);
3409  return 0;
3410  }
3411 
3412  ast_string_field_set(props, exten, exten);
3413 
3414  /* Fill the variable with the extension and context we want to call */
3415  snprintf(destination, sizeof(destination), "%s@%s", props->exten, props->context);
3416 
3417  ast_debug(1, "Channel %s: Attended transfer target '%s'\n",
3418  ast_channel_name(bridge_channel->chan), destination);
3419 
3420  /* Get a channel that is the destination we wish to call */
3421  props->transfer_target = dial_transfer(bridge_channel->chan, destination);
3422  if (!props->transfer_target) {
3423  ast_log(LOG_ERROR, "Channel %s: Unable to request outbound channel for attended transfer target.\n",
3424  ast_channel_name(bridge_channel->chan));
3425  stream_failsound(props->transferer);
3426  ast_bridge_channel_write_unhold(bridge_channel);
3428  return 0;
3429  }
3430 
3431 
3432  /* Create a bridge to use to talk to the person we are calling */
3434  if (!props->target_bridge) {
3435  ast_log(LOG_ERROR, "Channel %s: Unable to create bridge for attended transfer target.\n",
3436  ast_channel_name(bridge_channel->chan));
3437  stream_failsound(props->transferer);
3438  ast_bridge_channel_write_unhold(bridge_channel);
3439  ast_hangup(props->transfer_target);
3440  props->transfer_target = NULL;
3442  return 0;
3443  }
3445 
3446  if (attach_framehook(props, props->transfer_target)) {
3447  ast_log(LOG_ERROR, "Channel %s: Unable to attach framehook to transfer target.\n",
3448  ast_channel_name(bridge_channel->chan));
3449  stream_failsound(props->transferer);
3450  ast_bridge_channel_write_unhold(bridge_channel);
3451  ast_hangup(props->transfer_target);
3452  props->transfer_target = NULL;
3454  return 0;
3455  }
3456 
3461 
3462  if (ast_call(props->transfer_target, destination, 0)) {
3463  ast_log(LOG_ERROR, "Channel %s: Unable to place outbound call to transfer target.\n",
3464  ast_channel_name(bridge_channel->chan));
3465  stream_failsound(props->transferer);
3466  ast_bridge_channel_write_unhold(bridge_channel);
3467  ast_hangup(props->transfer_target);
3468  props->transfer_target = NULL;
3470  return 0;
3471  }
3472 
3473  /* We increase the refcount of the transfer target because ast_bridge_impart() will
3474  * steal the reference we already have. We need to keep a reference, so the only
3475  * choice is to give it a bump
3476  */
3478  if (ast_bridge_impart(props->target_bridge, props->transfer_target, NULL, NULL,
3480  ast_log(LOG_ERROR, "Channel %s: Unable to place transfer target into bridge.\n",
3481  ast_channel_name(bridge_channel->chan));
3482  stream_failsound(props->transferer);
3483  ast_bridge_channel_write_unhold(bridge_channel);
3484  ast_hangup(props->transfer_target);
3485  props->transfer_target = NULL;
3487  return 0;
3488  }
3489 
3490  if (ast_pthread_create_detached(&thread, NULL, attended_transfer_monitor_thread, props)) {
3491  ast_log(LOG_ERROR, "Channel %s: Unable to create monitoring thread for attended transfer.\n",
3492  ast_channel_name(bridge_channel->chan));
3493  stream_failsound(props->transferer);
3494  ast_bridge_channel_write_unhold(bridge_channel);
3496  return 0;
3497  }
3498 
3499  /* Once the monitoring thread has been created, it is responsible for destroying all
3500  * of the necessary components.
3501  */
3502  return 0;
3503 }
static void attended_transfer_properties_shutdown(struct attended_transfer_properties *props)
Initiate shutdown of attended transfer properties.
static void bridge_basic_change_personality(struct ast_bridge *bridge, enum bridge_basic_personality_type type, void *user_data)
Change basic bridge personality.
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.
const ast_string_field uniqueid
Definition: bridge.h:401
const char * name
Definition: bridge.h:259
struct ast_bridge * transferee_bridge
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6461
pthread_t thread
Definition: app_sla.c:329
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed...
Definition: bridge.h:384
static void stream_failsound(struct ast_channel *chan)
Helper method to stream a fail sound on a channel.
const ast_string_field exten
struct ast_channel * transfer_target
static struct ast_channel * dial_transfer(struct ast_channel *caller, const char *destination)
Helper function that creates an outgoing channel and returns it immediately.
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
void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request)
Adjust the bridge merge inhibit request count.
Definition: bridge.c:3000
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define AST_MAX_EXTENSION
Definition: channel.h:134
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.
#define ast_debug(level,...)
Log a DEBUG message.
const struct ast_bridge_methods * v_table
Definition: bridge.h:351
struct ast_bridge * target_bridge
Structure that contains information about a bridge.
Definition: bridge.h:349
static void * attended_transfer_monitor_thread(void *data)
The main loop for the attended transfer monitor thread.
#define AST_MAX_CONTEXT
Definition: channel.h:135
static struct attended_transfer_properties * attended_transfer_properties_alloc(struct ast_channel *transferer, const char *context)
Allocate and initialize attended transfer properties.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
Structure that contains configuration information for the attended transfer built in feature...
int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, const char *moh_class)
Write a hold frame into the bridge.
struct ast_channel * chan
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
const ast_string_field context
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
struct ast_channel * transferer
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
Collection of data related to an attended transfer attempt.
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.

References ast_channel_get_bridge(), get_transfer_parties_transferer_bridge(), and get_transfer_party_non_transferer_bridge().

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_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.
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...
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10534
Structure that contains information about a bridge.
Definition: bridge.h:349
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.

References ast_bridge_peer(), and get_transfer_party_non_transferer_bridge().

Referenced by get_transfer_parties().

1612 {
1613  *transferer_peer = ast_bridge_peer(transferer_bridge, transferer);
1614  get_transfer_party_non_transferer_bridge(other_bridge, other_party);
1615 }
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_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
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.

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

Referenced by get_transfer_parties(), and get_transfer_parties_transferer_bridge().

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
struct ast_bridge_channels_list channels
Definition: bridge.h:363
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
unsigned int num_channels
Definition: bridge.h:373
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 3180 of file bridge_basic.c.

References ao2_ref, ast_app_dtget(), ast_copy_string(), AST_DIGIT_NONE, ast_exists_extension(), ast_stopstream(), ast_strdupa, ast_stream_and_wait(), ast_test_suite_event_notify, 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().

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

References play_sound().

1753 {
1754  char *sound;
1755 
1756  ast_channel_lock(chan);
1757  sound = ast_get_chan_features_xferfailsound(chan);
1758  ast_channel_unlock(chan);
1759 
1760  if (sound) {
1761  play_sound(chan, sound);
1762  ast_free(sound);
1763  }
1764 }
static void play_sound(struct ast_channel *chan, const char *sound)
Helper method to play a sound on a channel in a bridge.
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.

References ao2_ref, ast_bridge_channel_queue_playfile(), and ast_channel_get_bridge_channel().

Referenced by play_failsound().

1734 {
1735  struct ast_bridge_channel *bridge_channel;
1736 
1737  ast_channel_lock(chan);
1738  bridge_channel = ast_channel_get_bridge_channel(chan);
1739  ast_channel_unlock(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 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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
Structure that contains information regarding a channel in a bridge.
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.
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 2410 of file bridge_basic.c.

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::recall_target, STIMULUS_RECALL_TARGET_ANSWER, and STIMULUS_RECALL_TARGET_HANGUP.

2411 {
2413 
2414  switch (ast_dial_state(dial)) {
2415  default:
2421  /* Failure cases */
2422  stimulate_attended_transfer(props, STIMULUS_RECALL_TARGET_HANGUP);
2423  break;
2428  /* Don't care about these cases */
2429  break;
2431  /* We struck gold! */
2432  props->recall_target = ast_dial_answered_steal(dial);
2433  stimulate_attended_transfer(props, STIMULUS_RECALL_TARGET_ANSWER);
2434  break;
2435  }
2436 }
void * ast_dial_get_user_data(struct ast_dial *dial)
Return the user data on a dial structure.
Definition: dial.c:1279
struct ast_channel * recall_target
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:1008
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
Definition: dial.c:989
Collection of data related to an attended transfer attempt.
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.

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::channels, ast_bridge_channel::features, lock, and SCOPED_LOCK.

Referenced by bridge_basic_change_personality().

720 {
721  struct ast_bridge_channel *iter;
722 
723  AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
726  }
727 }
struct ast_bridge_features * features
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
ast_mutex_t lock
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:583
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
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
struct ast_bridge_channels_list channels
Definition: bridge.h:363
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
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.

References AST_DIGIT_NONE, and ast_stream_and_wait().

Referenced by feature_attended_transfer().

1772 {
1773  char *sound;
1774 
1775  ast_channel_lock(chan);
1776  sound = ast_get_chan_features_xferfailsound(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 }
#define AST_DIGIT_NONE
Definition: file.h:47
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
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 2840 of file bridge_basic.c.

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, STIMULUS_RECALL_TARGET_ANSWER, STIMULUS_TRANSFER_TARGET_ANSWER, ast_frame::subclass, attended_transfer_properties::superstate, SUPERSTATE_TRANSFER, and attended_transfer_properties::target_framehook_id.

2842 {
2843  struct attended_transfer_properties *props = data;
2844 
2846  frame && frame->frametype == AST_FRAME_CONTROL &&
2847  frame->subclass.integer == AST_CONTROL_ANSWER &&
2848  !ast_check_hangup(chan)) {
2849 
2850  ast_debug(1, "Detected an answer for recall attempt on attended transfer %p\n", props);
2851  if (props->superstate == SUPERSTATE_TRANSFER) {
2852  stimulate_attended_transfer(props, STIMULUS_TRANSFER_TARGET_ANSWER);
2853  } else {
2854  stimulate_attended_transfer(props, STIMULUS_RECALL_TARGET_ANSWER);
2855  }
2857  props->target_framehook_id = -1;
2858  }
2859 
2860  return frame;
2861 }
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
Definition: astman.c:222
struct ast_frame_subclass subclass
#define ast_debug(level,...)
Log a DEBUG message.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
Transfer superstate.
Definition: bridge_basic.c:752
enum ast_frame_type frametype
enum attended_transfer_superstate superstate
Collection of data related to an attended transfer attempt.

Variable Documentation

const struct ast_datastore_info dtmf_features_info
static
Initial value:
= {
.type = "bridge-dtmf-features",
.destroy = ast_free_ptr,
}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739

Definition at line 82 of file bridge_basic.c.

const char* stimulus_strs[]

String representations of the various stimuli.

Used for debugging purposes

Definition at line 1267 of file bridge_basic.c.