Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Typedefs | Functions | Variables
bridge_channel.c File Reference

Bridging Channel API. More...

#include "asterisk.h"
#include <signal.h>
#include "asterisk/heap.h"
#include "asterisk/alertpipe.h"
#include "asterisk/astobj2.h"
#include "asterisk/stringfields.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/timing.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_channel.h"
#include "asterisk/bridge_after.h"
#include "asterisk/bridge_channel_internal.h"
#include "asterisk/bridge_internal.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features_config.h"
#include "asterisk/parking.h"
#include "asterisk/causes.h"
#include "asterisk/test.h"
#include "asterisk/sem.h"
#include "asterisk/stream.h"
#include "asterisk/message.h"
Include dependency graph for bridge_channel.c:

Go to the source code of this file.

Data Structures

struct  blind_transfer_data
 Data specifying where a blind transfer is going to. More...
 
struct  bridge_custom_callback
 
struct  bridge_park
 
struct  bridge_playfile
 
struct  bridge_run_app
 
struct  bridge_sync
 Synchronous bridge action object. More...
 
struct  sync_payload
 Frame payload for synchronous bridge actions. More...
 
struct  sync_structs
 List holding active synchronous action objects. More...
 

Macros

#define PLAYBACK_TIMEOUT   (600 * 1000)
 Failsafe for synchronous bridge action waiting. More...
 

Typedefs

typedef int(* ast_bridge_channel_post_action_data) (struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
 Used to queue an action frame onto a bridge channel and write an action frame into a bridge. More...
 

Functions

static void after_bridge_move_channel (struct ast_channel *chan_bridged, void *data)
 
static void after_bridge_move_channel_fail (enum ast_bridge_after_cb_reason reason, void *data)
 
void ast_bridge_channel_feature_digit (struct ast_bridge_channel *bridge_channel, int digit)
 Add a DTMF digit to the collected digits to match against DTMF features. More...
 
void ast_bridge_channel_feature_digit_add (struct ast_bridge_channel *bridge_channel, int digit)
 Add a DTMF digit to the collected digits. More...
 
struct ast_channelast_bridge_channel_get_chan (struct ast_bridge_channel *bridge_channel)
 Get a ref to the bridge_channel's ast_channel. More...
 
void ast_bridge_channel_kick (struct ast_bridge_channel *bridge_channel, int cause)
 Kick the channel out of the bridge. More...
 
void ast_bridge_channel_leave_bridge (struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
 Set bridge channel state to leave bridge (if not leaving already). More...
 
void ast_bridge_channel_leave_bridge_nolock (struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
 Set bridge channel state to leave bridge (if not leaving already). More...
 
void ast_bridge_channel_lock_bridge (struct ast_bridge_channel *bridge_channel)
 Lock the bridge associated with the bridge channel. More...
 
struct ast_bridgeast_bridge_channel_merge_inhibit (struct ast_bridge_channel *bridge_channel, int request)
 Adjust the bridge_channel's bridge merge inhibit request count. More...
 
int ast_bridge_channel_notify_talking (struct ast_bridge_channel *bridge_channel, int started_talking)
 Lets the bridging indicate when a bridge channel has stopped or started talking. More...
 
struct ast_bridge_channelast_bridge_channel_peer (struct ast_bridge_channel *bridge_channel)
 Get the peer bridge channel of a two party bridge. More...
 
void ast_bridge_channel_playfile (struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
 Play a file on the bridge channel. More...
 
int ast_bridge_channel_queue_app (struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
 Queue a bridge action run application frame onto the bridge channel. More...
 
int ast_bridge_channel_queue_callback (struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
 Queue a bridge action custom callback frame onto the bridge channel. More...
 
int ast_bridge_channel_queue_control_data (struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame onto the bridge channel with data. More...
 
int ast_bridge_channel_queue_frame (struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
 Write a frame to the specified bridge_channel. More...
 
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. More...
 
int ast_bridge_channel_queue_playfile_sync (struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
 Synchronously queue a bridge action play file frame onto the bridge channel. More...
 
void ast_bridge_channel_restore_formats (struct ast_bridge_channel *bridge_channel)
 Restore the formats of a bridge channel's channel to how they were before bridge_channel_internal_join. More...
 
void ast_bridge_channel_run_app (struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
 Run an application on the bridge channel. More...
 
void ast_bridge_channel_stream_map (struct ast_bridge_channel *bridge_channel)
 Maps a channel's stream topology to and from the bridge. More...
 
void ast_bridge_channel_update_accountcodes (struct ast_bridge_channel *joining, struct ast_bridge_channel *leaving)
 
void ast_bridge_channel_update_linkedids (struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 
int ast_bridge_channel_write_app (struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
 Write a bridge action run application frame into the bridge. More...
 
int ast_bridge_channel_write_callback (struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
 Write a bridge action custom callback frame into the bridge. More...
 
int ast_bridge_channel_write_control_data (struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
 Write a control frame into the bridge with data. More...
 
int ast_bridge_channel_write_hold (struct ast_bridge_channel *bridge_channel, const char *moh_class)
 Write a hold frame into the bridge. More...
 
int ast_bridge_channel_write_park (struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
 Have a bridge channel park a channel in the bridge. More...
 
int ast_bridge_channel_write_playfile (struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
 Write a bridge action play file frame into the bridge. More...
 
int ast_bridge_channel_write_unhold (struct ast_bridge_channel *bridge_channel)
 Write an unhold frame into the bridge. More...
 
int ast_bridge_queue_everyone_else (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 Queue the given frame to everyone else. More...
 
static void bridge_channel_attended_transfer (struct ast_bridge_channel *bridge_channel, const char *target_chan_name)
 
static void bridge_channel_blind_transfer (struct ast_bridge_channel *bridge_channel, struct blind_transfer_data *blind_data)
 
static void bridge_channel_cancel_owed_events (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_destroy (void *obj)
 
static void bridge_channel_dissolve_check (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_do_callback (struct ast_bridge_channel *bridge_channel, struct bridge_custom_callback *data)
 
static void bridge_channel_dtmf_stream (struct ast_bridge_channel *bridge_channel, const char *dtmf)
 Internal function that plays back DTMF on a bridge channel. More...
 
static void bridge_channel_event_join_leave (struct ast_bridge_channel *bridge_channel, enum ast_bridge_hook_type type)
 
static int bridge_channel_feature_digit_add (struct ast_bridge_channel *bridge_channel, int digit, size_t dtmf_len)
 
static unsigned int bridge_channel_feature_digit_timeout (struct ast_bridge_channel *bridge_channel)
 
static int bridge_channel_feature_timeout (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_handle_action (struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, void *data)
 
static void bridge_channel_handle_control (struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
 
static void bridge_channel_handle_feature_timeout (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_handle_interval (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_handle_write (struct ast_bridge_channel *bridge_channel)
 
struct ast_bridge_channelbridge_channel_internal_alloc (struct ast_bridge *bridge)
 
int bridge_channel_internal_allows_optimization (struct ast_bridge_channel *bridge_channel)
 
int bridge_channel_internal_join (struct ast_bridge_channel *bridge_channel)
 
void bridge_channel_internal_pull (struct ast_bridge_channel *bridge_channel)
 
int bridge_channel_internal_push (struct ast_bridge_channel *bridge_channel)
 
int bridge_channel_internal_push_full (struct ast_bridge_channel *bridge_channel, int optimized)
 
int bridge_channel_internal_queue_attended_transfer (struct ast_channel *transferee, struct ast_channel *unbridged_chan)
 
int bridge_channel_internal_queue_blind_transfer (struct ast_channel *transferee, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
 
void bridge_channel_internal_suspend_nolock (struct ast_bridge_channel *bridge_channel)
 
void bridge_channel_internal_unsuspend_nolock (struct ast_bridge_channel *bridge_channel)
 
static int bridge_channel_next_interval (struct ast_bridge_channel *bridge_channel)
 
static int bridge_channel_next_timeout (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_park (struct ast_bridge_channel *bridge_channel, struct bridge_park *payload)
 
static void bridge_channel_playfile (struct ast_bridge_channel *bridge_channel, struct bridge_playfile *payload)
 
static void bridge_channel_poke (struct ast_bridge_channel *bridge_channel)
 
static int bridge_channel_queue_action_data (struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
 
static int bridge_channel_queue_action_data_sync (struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
 
void bridge_channel_queue_deferred_frames (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_run_app (struct ast_bridge_channel *bridge_channel, struct bridge_run_app *data)
 
void bridge_channel_settle_owed_events (struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_suspend (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_talking (struct ast_bridge_channel *bridge_channel, int talking)
 
static void bridge_channel_unsuspend (struct ast_bridge_channel *bridge_channel)
 
static void bridge_channel_update_accountcodes_joining (struct ast_bridge_channel *joining, struct ast_bridge_channel *swap)
 
static void bridge_channel_update_accountcodes_leaving (struct ast_bridge_channel *leaving)
 
static void bridge_channel_wait (struct ast_bridge_channel *bridge_channel)
 
static int bridge_channel_write_action_data (struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
 
static int bridge_channel_write_dtmf_stream (struct ast_bridge_channel *bridge_channel, const char *dtmf)
 
static int bridge_channel_write_frame (struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 
static void bridge_frame_free (struct ast_frame *frame)
 
static struct ast_framebridge_handle_dtmf (struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 Internal function to handle DTMF from a channel. More...
 
static void bridge_handle_trip (struct ast_bridge_channel *bridge_channel)
 
static void bridge_sync_cleanup (struct bridge_sync *sync_struct)
 Clean up a syncrhonization bridge object. More...
 
static void bridge_sync_init (struct bridge_sync *sync_struct, unsigned int id)
 initialize a synchronous bridge object. More...
 
static void bridge_sync_signal (struct bridge_sync *sync_struct)
 Signal that waiting for a synchronous bridge action is no longer necessary. More...
 
static void bridge_sync_wait (struct bridge_sync *sync_struct)
 Wait for a synchronous bridge action to complete. More...
 
static void channel_fill_empty_accountcode (struct ast_channel *dest, struct ast_channel *src)
 
static void channel_fill_empty_peeraccount (struct ast_channel *dest, struct ast_channel *src)
 
static int channel_set_cause (struct ast_channel *chan, int cause)
 
static void channel_set_empty_accountcodes (struct ast_channel *c0, struct ast_channel *c1)
 
static void channel_update_peeraccount (struct ast_channel *dest, struct ast_channel *src)
 
static void channel_update_peeraccounts (struct ast_channel *c0, struct ast_channel *c1)
 
static int payload_helper_app (ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
 
static int payload_helper_cb (ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
 
static int payload_helper_park (ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
 
static int payload_helper_playfile (ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
 
static int run_app_helper (struct ast_channel *chan, const char *app_name, const char *app_args)
 
static void sendtext_safe (struct ast_channel *chan, const struct ast_frame *f)
 
static void testsuite_notify_feature_success (struct ast_channel *chan, const char *dtmf)
 

Variables

static const char * controls []
 
static int sync_ids
 Counter used for assigning synchronous bridge action IDs. More...
 
static struct sync_structs sync_structs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 

Detailed Description

Bridging Channel API.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om
Richard Mudgett rmudg.nosp@m.ett@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Matt Jordan mjord.nosp@m.an@d.nosp@m.igium.nosp@m..com

Definition in file bridge_channel.c.

Macro Definition Documentation

◆ PLAYBACK_TIMEOUT

#define PLAYBACK_TIMEOUT   (600 * 1000)

Failsafe for synchronous bridge action waiting.

When waiting for a synchronous bridge action to complete, if there is a frame resource leak somewhere, it is possible that we will never get notified that the synchronous action completed.

If a significant amount of time passes, then we will abandon waiting for the synchrnous bridge action to complete.

This constant represents the number of milliseconds we will wait for the bridge action to complete.

Definition at line 178 of file bridge_channel.c.

Referenced by bridge_sync_wait().

Typedef Documentation

◆ ast_bridge_channel_post_action_data

typedef int(* ast_bridge_channel_post_action_data) (struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)

Used to queue an action frame onto a bridge channel and write an action frame into a bridge.

Since
12.0.0
Parameters
bridge_channelWhich channel work with.
actionType of bridge action frame.
dataFrame payload data to pass.
datalenFrame payload data length to pass.
Return values
0on success.
-1on error.

Definition at line 73 of file bridge_channel.c.

Function Documentation

◆ after_bridge_move_channel()

static void after_bridge_move_channel ( struct ast_channel chan_bridged,
void *  data 
)
static

Definition at line 1943 of file bridge_channel.c.

References ao2_cleanup, ast_alloca, ast_channel_caller(), ast_channel_connected(), ast_channel_connected_indicated(), ast_channel_lock, ast_channel_move(), ast_channel_queue_connected_line_update(), ast_channel_unlock, ast_connected_line_build_data(), ast_connected_line_copy_from_caller(), AST_CONTROL_READ_ACTION, AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_reset(), ast_queue_control_data(), ast_softhangup(), AST_SOFTHANGUP_DEV, frame_size, NULL, ast_control_read_action_payload::payload_size, ast_party_connected_line::priv, and RAII_VAR.

Referenced by bridge_channel_attended_transfer().

1944 {
1945  RAII_VAR(struct ast_channel *, chan_target, data, ao2_cleanup);
1946  struct ast_party_connected_line connected_target;
1947  unsigned char connected_line_data[1024];
1948  int payload_size;
1949 
1950  ast_party_connected_line_init(&connected_target);
1951 
1952  ast_channel_lock(chan_target);
1953  ast_party_connected_line_copy(&connected_target, ast_channel_connected(chan_target));
1954  ast_channel_unlock(chan_target);
1955  ast_party_id_reset(&connected_target.priv);
1956 
1957  if (ast_channel_move(chan_target, chan_bridged)) {
1958  ast_softhangup(chan_target, AST_SOFTHANGUP_DEV);
1959  ast_party_connected_line_free(&connected_target);
1960  return;
1961  }
1962 
1963  /* The ast_channel_move function will end up updating the connected line information
1964  * on chan_target to the value we have here, but will not inform it. To ensure that
1965  * AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO is executed we wipe it away here. If
1966  * we don't do this then the change will be considered redundant, since the connected
1967  * line information is already there (despite the channel not being told).
1968  */
1969  ast_channel_lock(chan_target);
1972  ast_channel_unlock(chan_target);
1973 
1974  if ((payload_size = ast_connected_line_build_data(connected_line_data,
1975  sizeof(connected_line_data), &connected_target, NULL)) != -1) {
1976  struct ast_control_read_action_payload *frame_payload;
1977  int frame_size;
1978 
1979  frame_size = payload_size + sizeof(*frame_payload);
1980  frame_payload = ast_alloca(frame_size);
1981  frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
1982  frame_payload->payload_size = payload_size;
1983  memcpy(frame_payload->payload, connected_line_data, payload_size);
1984  ast_queue_control_data(chan_target, AST_CONTROL_READ_ACTION, frame_payload, frame_size);
1985  }
1986 
1987  /* A connected line update is queued so that if chan_target is remotely involved with
1988  * anything (such as dialing a channel) the other channel(s) will be informed of the
1989  * new channel they are involved with.
1990  */
1991  ast_channel_lock(chan_target);
1992  ast_connected_line_copy_from_caller(&connected_target, ast_channel_caller(chan_target));
1993  ast_channel_queue_connected_line_update(chan_target, &connected_target, NULL);
1994  ast_channel_unlock(chan_target);
1995 
1996  ast_party_connected_line_free(&connected_target);
1997 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Build the connected line information data frame.
Definition: channel.c:8793
void ast_party_id_reset(struct ast_party_id *id)
Destroy and initialize the given party id structure.
Definition: channel.c:1896
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
#define NULL
Definition: resample.c:96
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
Move a channel from its current location to a new location.
Definition: channel.c:10867
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9202
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
Connected Line/Party information.
Definition: channel.h:457
#define ast_channel_unlock(chan)
Definition: channel.h:2946
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 ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8389
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
struct ast_party_connected_line * ast_channel_connected_indicated(struct ast_channel *chan)
static int frame_size[4]
Definition: format_g726.c:52

◆ after_bridge_move_channel_fail()

static void after_bridge_move_channel_fail ( enum ast_bridge_after_cb_reason  reason,
void *  data 
)
static

Definition at line 2003 of file bridge_channel.c.

References ao2_cleanup, ast_bridge_after_cb_reason_string(), ast_log, ast_softhangup(), AST_SOFTHANGUP_DEV, LOG_WARNING, and RAII_VAR.

Referenced by bridge_channel_attended_transfer().

2004 {
2005  RAII_VAR(struct ast_channel *, chan_target, data, ao2_cleanup);
2006 
2007  ast_log(LOG_WARNING, "Unable to complete transfer: %s\n",
2009  ast_softhangup(chan_target, AST_SOFTHANGUP_DEV);
2010 }
Main Channel structure associated with a channel.
const char * ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason)
Get a string representation of an after bridge callback reason.
Definition: bridge_after.c:296
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_bridge_channel_feature_digit()

void ast_bridge_channel_feature_digit ( struct ast_bridge_channel bridge_channel,
int  digit 
)

Add a DTMF digit to the collected digits to match against DTMF features.

Since
12.8.0
Parameters
bridge_channelChannel that received a DTMF digit.
digitDTMF digit to add to collected digits or 0 for timeout event.
clear_digitsclear the digits array prior to calling hooks
Note
Neither the bridge nor the bridge_channel locks should be held when entering this function.
This is intended to be called by bridge hooks and the bridge channel thread.
This is intended to be called by non-DTMF bridge hooks and the bridge channel thread. Calling from a DTMF bridge hook can potentially cause unbounded recursion.
Returns
Nothing

Definition at line 1762 of file bridge_channel.c.

References ao2_find, ao2_ref, ao2_unlink, ARRAY_LEN, ast_bridge_channel_kick(), ast_bridge_channel_lock_bridge(), ast_bridge_unlock, ast_channel_name(), ast_check_hangup_locked(), AST_CONTROL_SRCUPDATE, ast_debug, ast_indicate(), ast_samp2tv(), ast_test_suite_event_notify, ast_tvadd(), ast_tvnow(), ast_bridge_channel::bridge, bridge_channel_feature_digit_add(), bridge_channel_feature_digit_timeout(), bridge_channel_internal_suspend_nolock(), bridge_channel_unsuspend(), bridge_channel_write_dtmf_stream(), ast_bridge_hook::callback, ast_bridge_channel::chan, ast_bridge_hook_dtmf_parms::code, ast_bridge_channel::collected, ast_bridge_hook_dtmf::dtmf, ast_bridge_channel::dtmf_hook_state, ast_bridge_features::dtmf_hooks, ast_bridge_features::dtmf_passthrough, ast_bridge_channel::features, ast_bridge_hook_dtmf::generic, ast_bridge_hook::hook_pvt, ast_bridge_channel::interdigit_timeout, NULL, OBJ_SEARCH_PARTIAL_KEY, ast_bridge_channel::suspended, and testsuite_notify_feature_success().

Referenced by agent_alert(), bridge_channel_handle_feature_timeout(), bridge_channel_internal_join(), and bridge_handle_dtmf().

1763 {
1764  struct ast_bridge_features *features = bridge_channel->features;
1765  struct ast_bridge_hook_dtmf *hook = NULL;
1766  size_t dtmf_len;
1767 
1768  struct sanity_check_of_dtmf_size {
1769  char check[1 / (ARRAY_LEN(bridge_channel->dtmf_hook_state.collected) == ARRAY_LEN(hook->dtmf.code))];
1770  };
1771 
1772  dtmf_len = strlen(bridge_channel->dtmf_hook_state.collected);
1773  if (!dtmf_len && !digit) {
1774  /* Nothing to do */
1775  return;
1776  }
1777 
1778  if (digit) {
1779  dtmf_len = bridge_channel_feature_digit_add(bridge_channel, digit, dtmf_len);
1780  }
1781 
1782  while (digit) {
1783  /* See if a DTMF feature hook matches or can match */
1784  hook = ao2_find(features->dtmf_hooks, bridge_channel->dtmf_hook_state.collected,
1786  if (!hook) {
1787  ast_debug(1, "No DTMF feature hooks on %p(%s) match '%s'\n",
1788  bridge_channel, ast_channel_name(bridge_channel->chan),
1789  bridge_channel->dtmf_hook_state.collected);
1790  break;
1791  } else if (dtmf_len != strlen(hook->dtmf.code)) {
1792  unsigned int digit_timeout;
1793  /* Need more digits to match */
1794  ao2_ref(hook, -1);
1795  digit_timeout = bridge_channel_feature_digit_timeout(bridge_channel);
1796  bridge_channel->dtmf_hook_state.interdigit_timeout =
1797  ast_tvadd(ast_tvnow(), ast_samp2tv(digit_timeout, 1000));
1798  return;
1799  } else {
1800  int remove_me;
1801  int already_suspended;
1802 
1803  ast_debug(1, "DTMF feature hook %p matched DTMF string '%s' on %p(%s)\n",
1804  hook, bridge_channel->dtmf_hook_state.collected, bridge_channel,
1805  ast_channel_name(bridge_channel->chan));
1806 
1807  /*
1808  * Clear the collected digits before executing the hook
1809  * in case the hook starts another sequence.
1810  */
1811  bridge_channel->dtmf_hook_state.collected[0] = '\0';
1812 
1813  ast_bridge_channel_lock_bridge(bridge_channel);
1814  already_suspended = bridge_channel->suspended;
1815  if (!already_suspended) {
1817  }
1818  ast_bridge_unlock(bridge_channel->bridge);
1819  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
1820 
1821  /* Execute the matched hook on this channel. */
1822  remove_me = hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
1823  if (remove_me) {
1824  ast_debug(1, "DTMF hook %p is being removed from %p(%s)\n",
1825  hook, bridge_channel, ast_channel_name(bridge_channel->chan));
1826  ao2_unlink(features->dtmf_hooks, hook);
1827  }
1828  testsuite_notify_feature_success(bridge_channel->chan, hook->dtmf.code);
1829  ao2_ref(hook, -1);
1830 
1831  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
1832  if (!already_suspended) {
1833  bridge_channel_unsuspend(bridge_channel);
1834  }
1835 
1836  /*
1837  * If we are handing the channel off to an external hook for
1838  * ownership, we are not guaranteed what kind of state it will
1839  * come back in. If the channel hungup, we need to detect that
1840  * here if the hook did not already change the state.
1841  */
1842  if (bridge_channel->chan && ast_check_hangup_locked(bridge_channel->chan)) {
1843  ast_bridge_channel_kick(bridge_channel, 0);
1844  bridge_channel->dtmf_hook_state.collected[0] = '\0';
1845  return;
1846  }
1847 
1848  /* if there is dtmf that has been collected then loop back through,
1849  but set digit to -1 so it doesn't try to do an add since the dtmf
1850  is already in the buffer */
1851  dtmf_len = strlen(bridge_channel->dtmf_hook_state.collected);
1852  if (!dtmf_len) {
1853  return;
1854  }
1855  }
1856  }
1857 
1858  if (!digit) {
1859  ast_debug(1, "DTMF feature string collection on %p(%s) timed out\n",
1860  bridge_channel, ast_channel_name(bridge_channel->chan));
1861  }
1862 
1863  /* Timeout or DTMF digit didn't allow a match with any hooks. */
1864  if (features->dtmf_passthrough) {
1865  /* Stream the collected DTMF to the other channels. */
1866  bridge_channel_write_dtmf_stream(bridge_channel,
1867  bridge_channel->dtmf_hook_state.collected);
1868  }
1869  bridge_channel->dtmf_hook_state.collected[0] = '\0';
1870 
1871  ast_test_suite_event_notify("FEATURE_DETECTION", "Result: fail");
1872 }
char digit
struct ast_bridge_channel::@233 dtmf_hook_state
struct ast_bridge_features * features
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void bridge_channel_internal_suspend_nolock(struct ast_bridge_channel *bridge_channel)
Structure that contains features information.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
unsigned int suspended
struct ao2_container * dtmf_hooks
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
char collected[MAXIMUM_DTMF_FEATURE_STRING]
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1120
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
static unsigned int bridge_channel_feature_digit_timeout(struct ast_bridge_channel *bridge_channel)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
struct ast_bridge_hook_dtmf_parms dtmf
struct timeval interdigit_timeout
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
unsigned int dtmf_passthrough
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
ast_bridge_hook_callback callback
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ast_bridge_hook generic
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
static void testsuite_notify_feature_success(struct ast_channel *chan, const char *dtmf)
static int bridge_channel_write_dtmf_stream(struct ast_bridge_channel *bridge_channel, const char *dtmf)
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
char code[MAXIMUM_DTMF_FEATURE_STRING]
static void bridge_channel_unsuspend(struct ast_bridge_channel *bridge_channel)
static int bridge_channel_feature_digit_add(struct ast_bridge_channel *bridge_channel, int digit, size_t dtmf_len)

◆ ast_bridge_channel_feature_digit_add()

void ast_bridge_channel_feature_digit_add ( struct ast_bridge_channel bridge_channel,
int  digit 
)

Add a DTMF digit to the collected digits.

Since
13.3.0
Parameters
bridge_channelChannel that received a DTMF digit.
digitDTMF digit to add to collected digits
Note
Neither the bridge nor the bridge_channel locks should be held when entering this function.
This is can only be called from within DTMF bridge hooks.

Definition at line 1754 of file bridge_channel.c.

References bridge_channel_feature_digit_add(), ast_bridge_channel::collected, and ast_bridge_channel::dtmf_hook_state.

Referenced by play_file().

1755 {
1756  if (digit) {
1758  bridge_channel, digit, strlen(bridge_channel->dtmf_hook_state.collected));
1759  }
1760 }
char digit
struct ast_bridge_channel::@233 dtmf_hook_state
char collected[MAXIMUM_DTMF_FEATURE_STRING]
static int bridge_channel_feature_digit_add(struct ast_bridge_channel *bridge_channel, int digit, size_t dtmf_len)

◆ ast_bridge_channel_get_chan()

struct ast_channel* ast_bridge_channel_get_chan ( struct ast_bridge_channel bridge_channel)

Get a ref to the bridge_channel's ast_channel.

Parameters
bridge_channelThe bridge channel
Note
The returned channel NEEDS to be unref'd once you are done with it. In general, this function is best used when accessing the bridge_channel chan from outside of a bridging thread.
Return values
ref'dast_channel on success
NULLotherwise

Definition at line 211 of file bridge_channel.c.

References ao2_bump, ao2_lock, ao2_unlock, and ast_bridge_channel::chan.

Referenced by ast_bridge_channel_write_unhold().

212 {
213  struct ast_channel *chan;
214 
215  ao2_lock(bridge_channel);
216  chan = ao2_bump(bridge_channel->chan);
217  ao2_unlock(bridge_channel);
218 
219  return chan;
220 }
Main Channel structure associated with a channel.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ao2_lock(a)
Definition: astobj2.h:718
struct ast_channel * chan

◆ ast_bridge_channel_kick()

void ast_bridge_channel_kick ( struct ast_bridge_channel bridge_channel,
int  cause 
)

Kick the channel out of the bridge.

Since
12.0.0
Parameters
bridge_channelWhich channel is being kicked or hungup.
causeCause of channel being kicked. If cause <= 0 then use cause on channel if cause still <= 0 use AST_CAUSE_NORMAL_CLEARING.
Note
This is intended to be called by bridge hooks and the bridge channel thread.
Returns
Nothing

Definition at line 605 of file bridge_channel.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ao2_unlink, ast_bridge_channel_leave_bridge(), ast_bridge_channel_lock, ast_bridge_channel_unlock, AST_BRIDGE_HOOK_TYPE_HANGUP, ast_channel_name(), ast_debug, BRIDGE_CHANNEL_STATE_END, BRIDGE_CHANNEL_STATE_WAIT, ast_bridge_hook::callback, ast_bridge_channel::chan, channel_set_cause(), ast_bridge_channel::features, ast_bridge_hook::hook_pvt, ast_bridge_features::other_hooks, ast_bridge_channel::state, and ast_bridge_hook::type.

Referenced by ast_bridge_channel_feature_digit(), ast_bridge_channel_run_app(), bridge_channel_attended_transfer(), bridge_channel_blind_transfer(), bridge_channel_handle_action(), bridge_channel_internal_join(), bridge_handle_trip(), and kick_it().

606 {
607  struct ast_bridge_features *features = bridge_channel->features;
608  struct ast_bridge_hook *hook;
609  struct ao2_iterator iter;
610 
611  ast_bridge_channel_lock(bridge_channel);
612  if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
613  channel_set_cause(bridge_channel->chan, cause);
614  cause = 0;
615  }
616  ast_bridge_channel_unlock(bridge_channel);
617 
618  /* Run any hangup hooks. */
619  iter = ao2_iterator_init(features->other_hooks, 0);
620  for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
621  int remove_me;
622 
623  if (hook->type != AST_BRIDGE_HOOK_TYPE_HANGUP) {
624  continue;
625  }
626  remove_me = hook->callback(bridge_channel, hook->hook_pvt);
627  if (remove_me) {
628  ast_debug(1, "Hangup hook %p is being removed from %p(%s)\n",
629  hook, bridge_channel, ast_channel_name(bridge_channel->chan));
630  ao2_unlink(features->other_hooks, hook);
631  }
632  }
633  ao2_iterator_destroy(&iter);
634 
635  /* Default hangup action. */
637 }
struct ast_bridge_features * features
Structure that contains features information.
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
enum bridge_channel_state state
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
enum ast_bridge_hook_type type
static int channel_set_cause(struct ast_channel *chan, int cause)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
ast_bridge_hook_callback callback
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ast_channel * chan
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_container * other_hooks
const char * ast_channel_name(const struct ast_channel *chan)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
Structure that is the essence of a feature hook.

◆ ast_bridge_channel_leave_bridge()

void ast_bridge_channel_leave_bridge ( struct ast_bridge_channel bridge_channel,
enum bridge_channel_state  new_state,
int  cause 
)

Set bridge channel state to leave bridge (if not leaving already).

Parameters
bridge_channelChannel to change the state on
new_stateThe new state to place the channel into
causeCause of channel leaving bridge. If cause <= 0 then use cause on channel if cause still <= 0 use AST_CAUSE_NORMAL_CLEARING.

Example usage:

This places the channel pointed to by bridge_channel into the state BRIDGE_CHANNEL_STATE_END if it was BRIDGE_CHANNEL_STATE_WAIT before.

Definition at line 314 of file bridge_channel.c.

References ast_bridge_channel_leave_bridge_nolock(), ast_bridge_channel_lock, and ast_bridge_channel_unlock.

Referenced by _ast_bridge_channel_unlock(), agent_connect_caller(), ast_bridge_channel_kick(), ast_bridge_depart(), ast_bridge_remove(), basic_hangup_hook(), bridge_agent_hold_heartbeat(), bridge_agent_hold_push(), bridge_channel_complete_join(), bridge_channel_dissolve_check(), bridge_channel_internal_push_full(), bridge_dissolve(), bridge_do_merge(), bridge_do_move(), bridge_features_duration_callback(), bridge_swap_attended_transfer(), bridgewait_timeout_callback(), caller_joined_bridge(), caller_safety_timeout(), feature_hangup(), parking_duration_callback(), say_parking_space(), set_softmix_bridge_data(), try_swap_optimize_out(), and user_timeout().

315 {
316  ast_bridge_channel_lock(bridge_channel);
317  ast_bridge_channel_leave_bridge_nolock(bridge_channel, new_state, cause);
318  ast_bridge_channel_unlock(bridge_channel);
319 }
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.

◆ ast_bridge_channel_leave_bridge_nolock()

void ast_bridge_channel_leave_bridge_nolock ( struct ast_bridge_channel bridge_channel,
enum bridge_channel_state  new_state,
int  cause 
)

Set bridge channel state to leave bridge (if not leaving already).

Parameters
bridge_channelChannel to change the state on
new_stateThe new state to place the channel into
causeCause of channel leaving bridge. If cause <= 0 then use cause on channel if cause still <= 0 use AST_CAUSE_NORMAL_CLEARING.

Example usage:

This places the channel pointed to by bridge_channel into the state BRIDGE_CHANNEL_STATE_END if it was BRIDGE_CHANNEL_STATE_WAIT before.

Definition at line 292 of file bridge_channel.c.

References ast_bridge_vars_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, bridge_channel_poke(), BRIDGE_CHANNEL_STATE_WAIT, ast_bridge_channel::chan, channel_set_cause(), NULL, and ast_bridge_channel::state.

Referenced by _ast_bridge_channel_unlock(), ast_bridge_channel_leave_bridge(), bridge_do_merge(), and caller_abort_agent().

293 {
294  if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
295  return;
296  }
297 
298  ast_debug(1, "Setting %p(%s) state from:%u to:%u\n",
299  bridge_channel, ast_channel_name(bridge_channel->chan), bridge_channel->state,
300  new_state);
301 
302  channel_set_cause(bridge_channel->chan, cause);
303 
304  ast_channel_lock(bridge_channel->chan);
305  ast_bridge_vars_set(bridge_channel->chan, NULL, NULL);
306  ast_channel_unlock(bridge_channel->chan);
307 
308  /* Change the state on the bridge channel */
309  bridge_channel->state = new_state;
310 
311  bridge_channel_poke(bridge_channel);
312 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void ast_bridge_vars_set(struct ast_channel *chan, const char *name, const char *pvtid)
Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel.
Definition: bridge.c:1242
enum bridge_channel_state state
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int channel_set_cause(struct ast_channel *chan, int cause)
static void bridge_channel_poke(struct ast_bridge_channel *bridge_channel)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)

◆ ast_bridge_channel_lock_bridge()

void ast_bridge_channel_lock_bridge ( struct ast_bridge_channel bridge_channel)

Lock the bridge associated with the bridge channel.

Since
12.0.0
Parameters
bridge_channelChannel that wants to lock the bridge.

This is an upstream lock operation. The defined locking order is bridge then bridge_channel.

Note
On entry, neither the bridge nor bridge_channel is locked.
The bridge_channel->bridge pointer changes because of a bridge-merge/channel-move operation between bridges.
Returns
Nothing

Definition at line 222 of file bridge_channel.c.

References ao2_ref, ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_bridge_lock, ast_bridge_unlock, and ast_bridge_channel::bridge.

Referenced by _ast_bridge_channel_unlock(), action_toggle_binaural(), agent_alert(), ast_bridge_channel_feature_digit(), ast_bridge_channel_merge_inhibit(), ast_bridge_notify_masquerade(), basic_hangup_hook(), bridge_channel_handle_control(), bridge_channel_internal_join(), bridge_channel_suspend(), bridge_channel_unsuspend(), bridge_channel_wait(), bridge_channel_write_frame(), bridge_handle_trip(), check_binaural_position_change(), deferred_action(), feature_automixmonitor(), feature_automonitor(), and parking_blind_transfer_park().

223 {
224  struct ast_bridge *bridge;
225 
226  for (;;) {
227  /* Safely get the bridge pointer */
228  ast_bridge_channel_lock(bridge_channel);
229  bridge = bridge_channel->bridge;
230  ao2_ref(bridge, +1);
231  ast_bridge_channel_unlock(bridge_channel);
232 
233  /* Lock the bridge and see if it is still the bridge we need to lock. */
234  ast_bridge_lock(bridge);
235  if (bridge == bridge_channel->bridge) {
236  ao2_ref(bridge, -1);
237  return;
238  }
239  ast_bridge_unlock(bridge);
240  ao2_ref(bridge, -1);
241  }
242 }
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

◆ ast_bridge_channel_merge_inhibit()

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.

Since
12.0.0
Parameters
bridge_channelWhat to operate on.
requestInhibit request increment. (Positive to add requests. Negative to remove requests.)
Note
This API call is meant for internal bridging operations.
Return values
bridgeadjusted merge inhibit with reference count.

Definition at line 369 of file bridge_channel.c.

References ao2_ref, ast_bridge_channel_lock_bridge(), ast_bridge_unlock, ast_bridge_channel::bridge, and bridge_merge_inhibit_nolock().

Referenced by _ast_bridge_channel_unlock(), and feature_attended_transfer().

370 {
371  struct ast_bridge *bridge;
372 
373  ast_bridge_channel_lock_bridge(bridge_channel);
374  bridge = bridge_channel->bridge;
375  ao2_ref(bridge, +1);
377  ast_bridge_unlock(bridge);
378  return bridge;
379 }
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request)
Definition: bridge.c:3052
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
static int request(void *obj)
Definition: chan_pjsip.c:2559
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.

◆ ast_bridge_channel_notify_talking()

int ast_bridge_channel_notify_talking ( struct ast_bridge_channel bridge_channel,
int  started_talking 
)

Lets the bridging indicate when a bridge channel has stopped or started talking.

Note
All DSP functionality on the bridge has been pushed down to the lowest possible layer, which in this case is the specific bridging technology being used. Since it is necessary for the knowledge of which channels are talking to make its way up to the application, this function has been created to allow the bridging technology to communicate that information with the bridging core.
Parameters
bridge_channelThe bridge channel that has either started or stopped talking.
started_talkingset to 1 when this indicates the channel has started talking set to 0 when this indicates the channel has stopped talking.
Return values
0on success.
-1on error.

Definition at line 244 of file bridge_channel.c.

References ast_bridge_channel_queue_frame(), AST_FRAME_BRIDGE_ACTION, BRIDGE_CHANNEL_ACTION_TALKING_START, BRIDGE_CHANNEL_ACTION_TALKING_STOP, and ast_frame::frametype.

Referenced by _ast_bridge_channel_unlock(), clear_talking(), and softmix_bridge_write_voice().

245 {
246  struct ast_frame action = {
248  .subclass.integer = started_talking
250  };
251 
252  return ast_bridge_channel_queue_frame(bridge_channel, &action);
253 }
int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
Write a frame to the specified bridge_channel.
Data structure associated with a single frame of data.
enum ast_frame_type frametype

◆ ast_bridge_channel_peer()

struct ast_bridge_channel* ast_bridge_channel_peer ( struct ast_bridge_channel bridge_channel)

Get the peer bridge channel of a two party bridge.

Since
12.0.0
Parameters
bridge_channelWhat to get the peer of.
Note
On entry, bridge_channel->bridge is already locked.
This is an internal bridge function.
Return values
peeron success.
NULLno peer channel.

Definition at line 321 of file bridge_channel.c.

References AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge::channels, ast_bridge_channel::in_bridge, NULL, and ast_bridge::num_channels.

Referenced by _ast_bridge_channel_unlock(), bridge_reconfigured_connected_line_update(), bridge_swap_attended_transfer(), parking_blind_transfer_park(), and try_swap_optimize_out().

322 {
323  struct ast_bridge *bridge = bridge_channel->bridge;
324  struct ast_bridge_channel *other = NULL;
325 
326  if (bridge_channel->in_bridge && bridge->num_channels == 2) {
327  AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
328  if (other != bridge_channel) {
329  break;
330  }
331  }
332  }
333 
334  return other;
335 }
#define NULL
Definition: resample.c:96
struct ast_bridge * bridge
Bridge this channel is participating in.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
unsigned int in_bridge
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
unsigned int num_channels
Definition: bridge.h:381

◆ ast_bridge_channel_playfile()

void ast_bridge_channel_playfile ( struct ast_bridge_channel bridge_channel,
ast_bridge_custom_play_fn  custom_play,
const char *  playfile,
const char *  moh_class 
)

Play a file on the bridge channel.

Since
12.0.0
Parameters
bridge_channelWhich channel to play the file on
custom_playCall this function to play the playfile. (NULL if normal sound file to play)
playfileSound filename to play.
moh_classMOH class to request bridge peers to hear while file is played. NULL if no MOH. Empty if default MOH class.
Note
This is intended to be called by bridge hooks.
Returns
Nothing

Definition at line 1321 of file bridge_channel.c.

References ast_bridge_channel_write_hold(), ast_bridge_channel_write_unhold(), ast_channel_flags(), ast_channel_latest_musicclass(), ast_channel_lock, ast_channel_unlock, AST_DIGIT_NONE, AST_FLAG_MOH, ast_moh_start(), ast_strdupa, ast_stream_and_wait(), ast_test_flag, ast_bridge_channel::chan, and NULL.

Referenced by bridge_channel_playfile().

1322 {
1323  if (moh_class) {
1324  ast_bridge_channel_write_hold(bridge_channel, moh_class);
1325  }
1326  if (custom_play) {
1327  custom_play(bridge_channel, playfile);
1328  } else {
1329  ast_stream_and_wait(bridge_channel->chan, playfile, AST_DIGIT_NONE);
1330  }
1331  if (moh_class) {
1332  ast_bridge_channel_write_unhold(bridge_channel);
1333  }
1334 
1335  /*
1336  * It may be necessary to resume music on hold after we finish
1337  * playing the announcment.
1338  */
1339  if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
1340  const char *latest_musicclass;
1341 
1342  ast_channel_lock(bridge_channel->chan);
1343  latest_musicclass = ast_strdupa(ast_channel_latest_musicclass(bridge_channel->chan));
1344  ast_channel_unlock(bridge_channel->chan);
1345  ast_moh_start(bridge_channel->chan, latest_musicclass, NULL);
1346  }
1347 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define NULL
Definition: resample.c:96
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
const char * ast_channel_latest_musicclass(const struct ast_channel *chan)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define AST_DIGIT_NONE
Definition: file.h:47
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
#define ast_channel_unlock(chan)
Definition: channel.h:2946
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:1814
struct ast_channel * chan
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_flags * ast_channel_flags(struct ast_channel *chan)

◆ ast_bridge_channel_queue_app()

int ast_bridge_channel_queue_app ( struct ast_bridge_channel bridge_channel,
const char *  app_name,
const char *  app_args,
const char *  moh_class 
)

Queue a bridge action run application frame onto the bridge channel.

Since
12.0.0
Parameters
bridge_channelWhich channel to put the frame onto
app_nameDialplan application name.
app_argsArguments for the application. (NULL or empty for no arguments)
moh_classMOH class to request bridge peers to hear while application is running. NULL if no MOH. Empty if default MOH class.
Note
This is intended to be called by bridge hooks.
Return values
0on success.
-1on error.

Definition at line 1315 of file bridge_channel.c.

References bridge_channel_queue_action_data(), and payload_helper_app().

Referenced by _ast_bridge_channel_unlock().

1316 {
1318  bridge_channel, app_name, app_args, moh_class);
1319 }
static int bridge_channel_queue_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
static int payload_helper_app(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463

◆ ast_bridge_channel_queue_callback()

int ast_bridge_channel_queue_callback ( struct ast_bridge_channel bridge_channel,
enum ast_bridge_channel_custom_callback_option  flags,
ast_bridge_custom_callback_fn  callback,
const void *  payload,
size_t  payload_size 
)

Queue a bridge action custom callback frame onto the bridge channel.

Since
12.0.0
Parameters
bridge_channelWhich channel to put the frame onto.
flagsCustom callback option flags.
callbackCustom callback run on a bridge channel.
payloadData to pass to the callback. (NULL if none).
payload_sizeSize of the payload if payload is non-NULL. A number otherwise.
Note
The payload MUST NOT have any resources that need to be freed.
This is intended to be called by bridge hooks.
Return values
0on success.
-1on error.

Definition at line 1492 of file bridge_channel.c.

References bridge_channel_queue_action_data(), and payload_helper_cb().

Referenced by ast_bridge_kick(), defer_action(), handle_bridge_kick_channel(), and send_alert_to_agent().

1495 {
1497  bridge_channel, flags, callback, payload, payload_size);
1498 }
static int bridge_channel_queue_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
static int payload_helper_cb(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)

◆ ast_bridge_channel_queue_control_data()

int ast_bridge_channel_queue_control_data ( struct ast_bridge_channel bridge_channel,
enum ast_control_frame_type  control,
const void *  data,
size_t  datalen 
)

Queue a control frame onto the bridge channel with data.

Since
12.0.0
Parameters
bridge_channelWhich channel to queue the frame onto.
controlType of control frame.
dataFrame payload data to pass.
datalenFrame payload data length to pass.
Return values
0on success.
-1on error.

Definition at line 1143 of file bridge_channel.c.

References ast_bridge_channel_queue_frame(), AST_FRAME_CONTROL, ast_frame::datalen, and ast_frame::frametype.

Referenced by _ast_bridge_channel_unlock(), bridge_reconfigured_connected_line_update(), and send_colp_to_agent().

1144 {
1145  struct ast_frame frame = {
1147  .subclass.integer = control,
1148  .datalen = datalen,
1149  .data.ptr = (void *) data,
1150  };
1151 
1152  return ast_bridge_channel_queue_frame(bridge_channel, &frame);
1153 }
int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
Write a frame to the specified bridge_channel.
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype

◆ ast_bridge_channel_queue_frame()

int ast_bridge_channel_queue_frame ( struct ast_bridge_channel bridge_channel,
struct ast_frame fr 
)

Write a frame to the specified bridge_channel.

Since
12.0.0
Parameters
bridge_channelChannel to queue the frame.
frFrame to write.
Return values
0on success.
-1on error.

Definition at line 1044 of file bridge_channel.c.

References ast_bridge_channel::alert_pipe, ast_alertpipe_write(), ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_channel_name(), AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_IMAGE, AST_FRAME_NULL, AST_FRAME_RTCP, AST_FRAME_TEXT, AST_FRAME_TEXT_DATA, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup, ast_is_deferrable_frame(), AST_LIST_INSERT_TAIL, ast_log, AST_MSG_DATA_ATTR_BODY, AST_MSG_DATA_ATTR_FROM, AST_MSG_DATA_ATTR_TO, ast_msg_data_get_attribute(), AST_VECTOR_GET, AST_VECTOR_SIZE, BRIDGE_CHANNEL_STATE_WAIT, bridge_frame_free(), ast_bridge_channel::chan, ast_frame::data, ast_frame::datalen, DEBUG_ATLEAST, ast_bridge_channel::features, ast_frame::frametype, LOG_DEBUG, LOG_ERROR, ast_frame::ptr, ast_bridge_channel::state, ast_bridge_channel::stream_map, ast_frame::stream_num, ast_bridge_channel::suspended, ast_bridge_features::text_messaging, ast_bridge_channel::to_channel, and ast_bridge_channel::wr_queue.

Referenced by _ast_bridge_channel_unlock(), ast_bridge_channel_notify_talking(), ast_bridge_channel_queue_control_data(), ast_bridge_queue_everyone_else(), bridge_channel_queue_action_data(), bridge_channel_queue_action_data_sync(), remb_send_report(), send_message(), softmix_mixing_loop(), and softmix_pass_video_top_priority().

1045 {
1046  struct ast_frame *dup;
1047 
1048  if (bridge_channel->suspended
1049  /* Also defer DTMF frames. */
1051  && fr->frametype != AST_FRAME_DTMF_END
1052  && !ast_is_deferrable_frame(fr)) {
1053  /* Drop non-deferable frames when suspended. */
1054  return 0;
1055  }
1056  if (fr->frametype == AST_FRAME_NULL) {
1057  /* "Accept" the frame and discard it. */
1058  return 0;
1059  }
1060 
1061  if ((fr->frametype == AST_FRAME_VOICE || fr->frametype == AST_FRAME_VIDEO ||
1063  fr->frametype == AST_FRAME_RTCP) && fr->stream_num > -1) {
1064  int num = -1;
1065 
1066  ast_bridge_channel_lock(bridge_channel);
1067  if (fr->stream_num < (int)AST_VECTOR_SIZE(&bridge_channel->stream_map.to_channel)) {
1068  num = AST_VECTOR_GET(&bridge_channel->stream_map.to_channel, fr->stream_num);
1069  }
1070  ast_bridge_channel_unlock(bridge_channel);
1071 
1072  if (num == -1) {
1073  /* We don't have a mapped stream so just discard this frame. */
1074  return 0;
1075  }
1076  }
1077 
1078  dup = ast_frdup(fr);
1079  if (!dup) {
1080  return -1;
1081  }
1082 
1083  ast_bridge_channel_lock(bridge_channel);
1084  if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
1085  /* Drop frames on channels leaving the bridge. */
1086  ast_bridge_channel_unlock(bridge_channel);
1087  bridge_frame_free(dup);
1088  return 0;
1089  }
1090 
1091  if ((fr->frametype == AST_FRAME_TEXT || fr->frametype == AST_FRAME_TEXT_DATA) &&
1092  !bridge_channel->features->text_messaging) {
1093  /* This channel is not accepting text messages. */
1094  ast_bridge_channel_unlock(bridge_channel);
1095  bridge_frame_free(dup);
1096  return 0;
1097  }
1098 
1099  if (DEBUG_ATLEAST(1)) {
1100  if (fr->frametype == AST_FRAME_TEXT) {
1101  ast_log(LOG_DEBUG, "Queuing TEXT frame to '%s': %*.s\n", ast_channel_name(bridge_channel->chan),
1102  fr->datalen, (char *)fr->data.ptr);
1103  } else if (fr->frametype == AST_FRAME_TEXT_DATA) {
1104  struct ast_msg_data *msg = fr->data.ptr;
1105  ast_log(LOG_DEBUG, "Queueing TEXT_DATA frame from '%s' to '%s:%s': %s\n",
1108  ast_channel_name(bridge_channel->chan),
1110  }
1111  }
1112 
1113  AST_LIST_INSERT_TAIL(&bridge_channel->wr_queue, dup, frame_list);
1114  if (ast_alertpipe_write(bridge_channel->alert_pipe)) {
1115  ast_log(LOG_ERROR, "We couldn't write alert pipe for %p(%s)... something is VERY wrong\n",
1116  bridge_channel, ast_channel_name(bridge_channel->chan));
1117  }
1118  ast_bridge_channel_unlock(bridge_channel);
1119  return 0;
1120 }
#define ast_frdup(fr)
Copies a frame.
struct ast_bridge_channel::@230 wr_queue
struct ast_bridge_features * features
enum bridge_channel_state state
unsigned int suspended
Structure used to transport a message through the frame core.
Definition: message.c:1406
struct ast_bridge_channel::@236 stream_map
#define LOG_DEBUG
Definition: logger.h:241
ssize_t ast_alertpipe_write(int alert_pipe[2])
Write an event to an alert pipe.
Definition: alertpipe.c:120
unsigned int text_messaging
#define ast_log
Definition: astobj2.c:42
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
struct ast_vector_int to_channel
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
Definition: message.c:1533
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
int ast_is_deferrable_frame(const struct ast_frame *frame)
Should we keep this frame for later?
Definition: channel.c:1467
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype
static void bridge_frame_free(struct ast_frame *frame)
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_bridge_channel_queue_playfile()

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.

Since
12.0.0
Parameters
bridge_channelWhich channel to put the frame onto.
custom_playCall this function to play the playfile. (NULL if normal sound file to play)
playfileSound filename to play.
moh_classMOH class to request bridge peers to hear while file is played. NULL if no MOH. Empty if default MOH class.
Note
This is intended to be called by bridge hooks.
Return values
0on success.
-1on error.

Definition at line 1404 of file bridge_channel.c.

References bridge_channel_queue_action_data(), and payload_helper_playfile().

Referenced by ast_bridge_add_channel(), bridge_parking_pull(), bridge_parking_push(), check_bridge_play_sound(), feature_automixmonitor(), feature_automonitor(), parker_parked_call_message_response(), play_sound(), start_automixmonitor(), start_automonitor(), stop_automixmonitor(), and stop_automonitor().

1405 {
1407  bridge_channel, custom_play, playfile, moh_class);
1408 }
static int payload_helper_playfile(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
static int bridge_channel_queue_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)

◆ ast_bridge_channel_queue_playfile_sync()

int ast_bridge_channel_queue_playfile_sync ( struct ast_bridge_channel bridge_channel,
ast_bridge_custom_play_fn  custom_play,
const char *  playfile,
const char *  moh_class 
)

Synchronously queue a bridge action play file frame onto the bridge channel.

Since
12.2.0
Parameters
bridge_channelWhich channel to put the frame onto.
custom_playCall this function to play the playfile. (NULL if normal sound file to play)
playfileSound filename to play.
moh_classMOH class to request bridge peers to hear while file is played. NULL if no MOH. Empty if default MOH class.

This function will block until the queued frame has been destroyed. This will happen either if an error occurs or if the queued playback finishes.

Note
No locks may be held when calling this function.
Return values
0The playback was successfully queued.
-1The playback could not be queued.

Definition at line 1410 of file bridge_channel.c.

References bridge_channel_queue_action_data_sync(), and payload_helper_playfile().

Referenced by parker_parked_call_message_response(), and play_uri().

1412 {
1414  bridge_channel, custom_play, playfile, moh_class);
1415 }
static int payload_helper_playfile(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
static int bridge_channel_queue_action_data_sync(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)

◆ ast_bridge_channel_restore_formats()

void ast_bridge_channel_restore_formats ( struct ast_bridge_channel bridge_channel)

Restore the formats of a bridge channel's channel to how they were before bridge_channel_internal_join.

Since
12.0.0
Parameters
bridge_channelChannel to restore

Definition at line 337 of file bridge_channel.c.

References ast_assert, ast_channel_lock, ast_channel_name(), ast_channel_readformat(), ast_channel_unlock, ast_channel_writeformat(), ast_debug, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), ast_set_read_format(), ast_set_write_format(), ast_bridge_channel::chan, NULL, ast_bridge_channel::read_format, and ast_bridge_channel::write_format.

Referenced by _ast_bridge_channel_unlock(), bridge_channel_internal_join(), and participant_reaction_announcer_leave().

338 {
339  ast_assert(bridge_channel->read_format != NULL);
340  ast_assert(bridge_channel->write_format != NULL);
341 
342  ast_channel_lock(bridge_channel->chan);
343 
344  /* Restore original formats of the channel as they came in */
345  if (ast_format_cmp(ast_channel_readformat(bridge_channel->chan), bridge_channel->read_format) == AST_FORMAT_CMP_NOT_EQUAL) {
346  ast_debug(1, "Bridge is returning %p(%s) to read format %s\n",
347  bridge_channel, ast_channel_name(bridge_channel->chan),
348  ast_format_get_name(bridge_channel->read_format));
349  if (ast_set_read_format(bridge_channel->chan, bridge_channel->read_format)) {
350  ast_debug(1, "Bridge failed to return %p(%s) to read format %s\n",
351  bridge_channel, ast_channel_name(bridge_channel->chan),
352  ast_format_get_name(bridge_channel->read_format));
353  }
354  }
355  if (ast_format_cmp(ast_channel_writeformat(bridge_channel->chan), bridge_channel->write_format) == AST_FORMAT_CMP_NOT_EQUAL) {
356  ast_debug(1, "Bridge is returning %p(%s) to write format %s\n",
357  bridge_channel, ast_channel_name(bridge_channel->chan),
358  ast_format_get_name(bridge_channel->write_format));
359  if (ast_set_write_format(bridge_channel->chan, bridge_channel->write_format)) {
360  ast_debug(1, "Bridge failed to return %p(%s) to write format %s\n",
361  bridge_channel, ast_channel_name(bridge_channel->chan),
362  ast_format_get_name(bridge_channel->write_format));
363  }
364  }
365 
366  ast_channel_unlock(bridge_channel->chan);
367 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_assert(a)
Definition: utils.h:695
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
struct ast_format * write_format
struct ast_format * read_format
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)

◆ ast_bridge_channel_run_app()

void ast_bridge_channel_run_app ( struct ast_bridge_channel bridge_channel,
const char *  app_name,
const char *  app_args,
const char *  moh_class 
)

Run an application on the bridge channel.

Since
12.0.0
Parameters
bridge_channelWhich channel to run the application on.
app_nameDialplan application name.
app_argsArguments for the application. (NULL tolerant)
moh_classMOH class to request bridge peers to hear while application is running. NULL if no MOH. Empty if default MOH class.
Note
This is intended to be called by bridge hooks.
Returns
Nothing

Definition at line 1241 of file bridge_channel.c.

References ast_bridge_channel_kick(), ast_bridge_channel_write_hold(), ast_bridge_channel_write_unhold(), AST_CAUSE_NORMAL_CLEARING, ast_bridge_channel::chan, run_app_helper(), and S_OR.

Referenced by _ast_bridge_channel_unlock(), bridge_channel_run_app(), and dynamic_dtmf_hook_callback().

1242 {
1243  if (moh_class) {
1244  ast_bridge_channel_write_hold(bridge_channel, moh_class);
1245  }
1246  if (run_app_helper(bridge_channel->chan, app_name, S_OR(app_args, ""))) {
1247  /* Break the bridge if the app returns non-zero. */
1249  }
1250  if (moh_class) {
1251  ast_bridge_channel_write_unhold(bridge_channel);
1252  }
1253 }
static int run_app_helper(struct ast_channel *chan, const char *app_name, const char *app_args)
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
struct ast_channel * chan
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, const char *moh_class)
Write a hold frame into the bridge.

◆ ast_bridge_channel_stream_map()

void ast_bridge_channel_stream_map ( struct ast_bridge_channel bridge_channel)

Maps a channel's stream topology to and from the bridge.

Since
15.0.0

When a channel joins a bridge or its associated stream topology is updated, each stream in the topology needs to be mapped according to its media type to the bridge. Calling this method creates a mapping of each stream on the channel indexed to the bridge's supported media types and vice versa (i.e. bridge's media types indexed to channel streams).

The first channel to join the bridge creates the initial order for the bridge's media types (e.g. a one to one mapping is made). Subsequently added channels are mapped to that order adding more media types if/when the newly added channel has more streams and/or media types specified by the bridge.

Parameters
bridge_channelChannel to map
Note
The bridge_channel's bridge must be locked prior to calling this function.
Returns
Nothing

Definition at line 3174 of file bridge_channel.c.

References ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_channel_get_stream_topology(), ast_channel_lock, ast_channel_unlock, ast_stream_topology_map(), ast_bridge_channel::bridge, ast_bridge_channel::chan, ast_bridge::media_types, ast_bridge_channel::stream_map, ast_bridge_channel::to_bridge, and ast_bridge_channel::to_channel.

Referenced by bridge_channel_complete_join(), bridge_handle_trip(), native_rtp_stream_topology_changed(), simple_bridge_stream_topology_changed(), and softmix_bridge_stream_topology_changed().

3175 {
3176  ast_bridge_channel_lock(bridge_channel);
3177  ast_channel_lock(bridge_channel->chan);
3179  &bridge_channel->bridge->media_types, &bridge_channel->stream_map.to_bridge,
3180  &bridge_channel->stream_map.to_channel);
3181  ast_channel_unlock(bridge_channel->chan);
3182  ast_bridge_channel_unlock(bridge_channel);
3183 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
struct ast_bridge_channel::@236 stream_map
struct ast_vector_int to_bridge
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
struct ast_vector_int to_channel
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan
struct ast_vector_int media_types
Definition: bridge.h:412
void ast_stream_topology_map(const struct ast_stream_topology *topology, struct ast_vector_int *types, struct ast_vector_int *v0, struct ast_vector_int *v1)
Map a given topology&#39;s streams to the given types.
Definition: stream.c:985

◆ ast_bridge_channel_update_accountcodes()

void ast_bridge_channel_update_accountcodes ( struct ast_bridge_channel joining,
struct ast_bridge_channel leaving 
)

Definition at line 596 of file bridge_channel.c.

References bridge_channel_update_accountcodes_joining(), and bridge_channel_update_accountcodes_leaving().

Referenced by _ast_bridge_channel_unlock(), bridge_basic_pull(), bridge_basic_push(), bridge_stasis_pull(), and bridge_stasis_push().

597 {
598  if (joining) {
600  } else {
602  }
603 }
static void bridge_channel_update_accountcodes_leaving(struct ast_bridge_channel *leaving)
static void bridge_channel_update_accountcodes_joining(struct ast_bridge_channel *joining, struct ast_bridge_channel *swap)

◆ ast_bridge_channel_update_linkedids()

void ast_bridge_channel_update_linkedids ( struct ast_bridge_channel bridge_channel,
struct ast_bridge_channel swap 
)

Definition at line 381 of file bridge_channel.c.

References ast_channel_internal_copy_linkedid(), ast_channel_internal_oldest_linkedid(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge_channel::chan, and ast_bridge::channels.

Referenced by _ast_bridge_channel_unlock(), bridge_basic_push(), and bridge_stasis_push().

382 {
383  struct ast_bridge_channel *other;
384  struct ast_bridge *bridge = bridge_channel->bridge;
385  struct ast_channel *oldest_linkedid_chan = bridge_channel->chan;
386 
387  AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
388  if (other == swap) {
389  continue;
390  }
391  oldest_linkedid_chan = ast_channel_internal_oldest_linkedid(
392  oldest_linkedid_chan, other->chan);
393  }
394 
395  ast_channel_lock(bridge_channel->chan);
396  ast_channel_internal_copy_linkedid(bridge_channel->chan, oldest_linkedid_chan);
397  ast_channel_unlock(bridge_channel->chan);
398  AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
399  if (other == swap) {
400  continue;
401  }
402  ast_channel_lock(other->chan);
403  ast_channel_internal_copy_linkedid(other->chan, oldest_linkedid_chan);
404  ast_channel_unlock(other->chan);
405  }
406 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
struct ast_bridge * bridge
Bridge this channel is participating in.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_channel_internal_copy_linkedid(struct ast_channel *dest, struct ast_channel *source)
Copy the full linkedid channel id structure from one channel to another.
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
struct ast_channel * ast_channel_internal_oldest_linkedid(struct ast_channel *a, struct ast_channel *b)
Determine which channel has an older linkedid.

◆ ast_bridge_channel_write_app()

int ast_bridge_channel_write_app ( struct ast_bridge_channel bridge_channel,
const char *  app_name,
const char *  app_args,
const char *  moh_class 
)

Write a bridge action run application frame into the bridge.

Since
12.0.0
Parameters
bridge_channelWhich channel is putting the frame into the bridge
app_nameDialplan application name.
app_argsArguments for the application. (NULL or empty for no arguments)
moh_classMOH class to request bridge peers to hear while application is running. NULL if no MOH. Empty if default MOH class.
Note
This is intended to be called by bridge hooks.
Return values
0on success.
-1on error.

Definition at line 1309 of file bridge_channel.c.

References bridge_channel_write_action_data(), and payload_helper_app().

Referenced by _ast_bridge_channel_unlock().

1310 {
1312  bridge_channel, app_name, app_args, moh_class);
1313 }
static int bridge_channel_write_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
static int payload_helper_app(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463

◆ ast_bridge_channel_write_callback()

int ast_bridge_channel_write_callback ( struct ast_bridge_channel bridge_channel,
enum ast_bridge_channel_custom_callback_option  flags,
ast_bridge_custom_callback_fn  callback,
const void *  payload,
size_t  payload_size 
)

Write a bridge action custom callback frame into the bridge.

Since
12.0.0
Parameters
bridge_channelWhich channel is putting the frame into the bridge
flagsCustom callback option flags.
callbackCustom callback run on a bridge channel.
payloadData to pass to the callback. (NULL if none).
payload_sizeSize of the payload if payload is non-NULL. A number otherwise.
Note
The payload MUST NOT have any resources that need to be freed.
This is intended to be called by bridge hooks.
Return values
0on success.
-1on error.

Definition at line 1484 of file bridge_channel.c.

References bridge_channel_write_action_data(), and payload_helper_cb().

Referenced by agent_connect_caller(), and dynamic_dtmf_hook_trip().

1487 {
1489  bridge_channel, flags, callback, payload, payload_size);
1490 }
static int bridge_channel_write_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
static int payload_helper_cb(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)

◆ ast_bridge_channel_write_control_data()

int ast_bridge_channel_write_control_data ( struct ast_bridge_channel bridge_channel,
enum ast_control_frame_type  control,
const void *  data,
size_t  datalen 
)

Write a control frame into the bridge with data.

Since
12.0.0
Parameters
bridge_channelWhich channel is putting the frame into the bridge.
controlType of control frame.
dataFrame payload data to pass.
datalenFrame payload data length to pass.
Return values
0on success.
-1on error.

Definition at line 1155 of file bridge_channel.c.

References AST_FRAME_CONTROL, bridge_channel_write_frame(), ast_frame::datalen, and ast_frame::frametype.

Referenced by _ast_bridge_channel_unlock(), agent_connect_caller(), ast_bridge_channel_write_hold(), ast_bridge_channel_write_unhold(), and ringing().

1156 {
1157  struct ast_frame frame = {
1159  .subclass.integer = control,
1160  .datalen = datalen,
1161  .data.ptr = (void *) data,
1162  };
1163 
1164  return bridge_channel_write_frame(bridge_channel, &frame);
1165 }
static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype

◆ ast_bridge_channel_write_hold()

int ast_bridge_channel_write_hold ( struct ast_bridge_channel bridge_channel,
const char *  moh_class 
)

Write a hold frame into the bridge.

Since
12.0.0
Parameters
bridge_channelWhich channel is putting the hold into the bridge.
moh_classThe suggested music class for the other end to use.
Return values
0on success.
-1on error.

Definition at line 1167 of file bridge_channel.c.

References ast_bridge_channel_write_control_data(), ast_channel_hold_type(), ast_channel_publish_cached_blob(), AST_CONTROL_HOLD, ast_json_pack(), ast_json_unref(), ast_strlen_zero, ast_bridge_channel::chan, and NULL.

Referenced by _ast_bridge_channel_unlock(), ast_bridge_channel_playfile(), ast_bridge_channel_run_app(), feature_attended_transfer(), feature_blind_transfer(), and hold().

1168 {
1169  struct ast_json *blob;
1170  int res;
1171  size_t datalen;
1172 
1173  if (!ast_strlen_zero(moh_class)) {
1174  datalen = strlen(moh_class) + 1;
1175 
1176  blob = ast_json_pack("{s: s}",
1177  "musicclass", moh_class);
1178  } else {
1179  moh_class = NULL;
1180  datalen = 0;
1181  blob = NULL;
1182  }
1183 
1185 
1187  moh_class, datalen);
1188 
1189  ast_json_unref(blob);
1190  return res;
1191 }
struct stasis_message_type * ast_channel_hold_type(void)
Message type for when a channel is placed on hold.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message using the latest snapshot from the cache.
#define NULL
Definition: resample.c:96
int ast_bridge_channel_write_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
Write a control frame into the bridge with data.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_channel * chan
Abstract JSON element (object, array, string, int, ...).

◆ ast_bridge_channel_write_park()

int ast_bridge_channel_write_park ( struct ast_bridge_channel bridge_channel,
const char *  parkee_uuid,
const char *  parker_uuid,
const char *  app_data 
)

Have a bridge channel park a channel in the bridge.

Since
12.0.0
Parameters
bridge_channelBridge channel performing the parking
parkee_uuidUnique id of the channel we want to park
parker_uuidUnique id of the channel parking the call
app_datastring indicating data used for park application (NULL allowed)
Note
This is intended to be called by bridge hooks.
Return values
0on success.
-1on error.

Definition at line 1555 of file bridge_channel.c.

References bridge_channel_write_action_data(), and payload_helper_park().

Referenced by manager_park_bridged(), and parking_blind_transfer_park().

1556 {
1558  bridge_channel, parkee_uuid, parker_uuid, app_data);
1559 }
static int bridge_channel_write_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
static int payload_helper_park(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, const char *parker_uuid, const char *app_data)

◆ ast_bridge_channel_write_playfile()

int ast_bridge_channel_write_playfile ( struct ast_bridge_channel bridge_channel,
ast_bridge_custom_play_fn  custom_play,
const char *  playfile,
const char *  moh_class 
)

Write a bridge action play file frame into the bridge.

Since
12.0.0
Parameters
bridge_channelWhich channel is putting the frame into the bridge
custom_playCall this function to play the playfile. (NULL if normal sound file to play)
playfileSound filename to play.
moh_classMOH class to request bridge peers to hear while file is played. NULL if no MOH. Empty if default MOH class.
Note
This is intended to be called by bridge hooks.
Return values
0on success.
-1on error.

Definition at line 1398 of file bridge_channel.c.

References bridge_channel_write_action_data(), and payload_helper_playfile().

Referenced by ast_bridge_transfer_attended(), start_automixmonitor(), start_automonitor(), stop_automixmonitor(), and stop_automonitor().

1399 {
1401  bridge_channel, custom_play, playfile, moh_class);
1402 }
static int bridge_channel_write_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
static int payload_helper_playfile(ast_bridge_channel_post_action_data post_it, struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)

◆ ast_bridge_channel_write_unhold()

int ast_bridge_channel_write_unhold ( struct ast_bridge_channel bridge_channel)

Write an unhold frame into the bridge.

Since
12.0.0
Parameters
bridge_channelWhich channel is putting the hold into the bridge.
Return values
0on success.
-1on error.

Definition at line 1193 of file bridge_channel.c.

References ao2_ref, ast_bridge_channel_get_chan(), ast_bridge_channel_write_control_data(), ast_channel_publish_cached_blob(), ast_channel_unhold_type(), AST_CONTROL_UNHOLD, and NULL.

Referenced by _ast_bridge_channel_unlock(), ast_bridge_channel_playfile(), ast_bridge_channel_run_app(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), feature_attended_transfer(), feature_blind_transfer(), and unhold().

1194 {
1195  struct ast_channel *chan = ast_bridge_channel_get_chan(bridge_channel);
1196 
1197  if (!chan) {
1198  return -1;
1199  }
1200 
1202  ao2_ref(chan, -1);
1203 
1205 }
Main Channel structure associated with a channel.
struct stasis_message_type * ast_channel_unhold_type(void)
Message type for when a channel is removed from hold.
void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message using the latest snapshot from the cache.
struct ast_channel * ast_bridge_channel_get_chan(struct ast_bridge_channel *bridge_channel)
Get a ref to the bridge_channel&#39;s ast_channel.
#define NULL
Definition: resample.c:96
int ast_bridge_channel_write_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
Write a control frame into the bridge with data.
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ ast_bridge_queue_everyone_else()

int ast_bridge_queue_everyone_else ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel,
struct ast_frame frame 
)

Queue the given frame to everyone else.

Since
12.0.0
Parameters
bridgeWhat bridge to distribute frame.
bridge_channelChannel to optionally not pass frame to. (NULL to pass to everyone)
frameFrame to pass.
Note
This is intended to be called by bridge hooks and bridge technologies.
Return values
0Frame written to at least one channel.
-1Frame written to no channels.

Definition at line 1122 of file bridge_channel.c.

References ast_bridge_channel_queue_frame(), AST_FRAME_NULL, AST_LIST_TRAVERSE, ast_bridge::channels, and ast_frame::frametype.

Referenced by bridge_hold(), bridge_ringing(), bridge_unhold(), holding_bridge_write(), native_bridge_write(), native_rtp_bridge_write(), simple_bridge_write(), softmix_bridge_write(), softmix_bridge_write_control(), softmix_bridge_write_text(), and softmix_bridge_write_video().

1123 {
1124  struct ast_bridge_channel *cur;
1125  int not_written = -1;
1126 
1127  if (frame->frametype == AST_FRAME_NULL) {
1128  /* "Accept" the frame and discard it. */
1129  return 0;
1130  }
1131 
1132  AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
1133  if (cur == bridge_channel) {
1134  continue;
1135  }
1136  if (!ast_bridge_channel_queue_frame(cur, frame)) {
1137  not_written = 0;
1138  }
1139  }
1140  return not_written;
1141 }
int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
Write a frame to the specified bridge_channel.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
enum ast_frame_type frametype

◆ bridge_channel_attended_transfer()

static void bridge_channel_attended_transfer ( struct ast_bridge_channel bridge_channel,
const char *  target_chan_name 
)
static

Definition at line 2027 of file bridge_channel.c.

References after_bridge_move_channel(), after_bridge_move_channel_fail(), ao2_cleanup, ao2_ref, ast_assert, ast_bridge_channel_kick(), ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_bridge_set_after_callback(), AST_CAUSE_NORMAL_CLEARING, ast_channel_get_by_name(), ast_channel_ref, ast_channel_unref, ast_softhangup(), AST_SOFTHANGUP_DEV, ast_bridge_channel::chan, NULL, and RAII_VAR.

Referenced by bridge_channel_handle_action().

2029 {
2030  RAII_VAR(struct ast_channel *, chan_target, NULL, ao2_cleanup);
2031  RAII_VAR(struct ast_channel *, chan_bridged, NULL, ao2_cleanup);
2032 
2033  chan_target = ast_channel_get_by_name(target_chan_name);
2034  if (!chan_target) {
2035  /* Dang, it disappeared somehow */
2037  return;
2038  }
2039 
2040  ast_bridge_channel_lock(bridge_channel);
2041  chan_bridged = bridge_channel->chan;
2042  ast_assert(chan_bridged != NULL);
2043  ao2_ref(chan_bridged, +1);
2044  ast_bridge_channel_unlock(bridge_channel);
2045 
2048  ast_softhangup(chan_target, AST_SOFTHANGUP_DEV);
2049 
2050  /* Release the ref we tried to pass to ast_bridge_set_after_callback(). */
2051  ast_channel_unref(chan_target);
2052  }
2054 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data)
Setup an after bridge callback for when the channel leaves the bridging system.
Definition: bridge_after.c:259
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
static void after_bridge_move_channel_fail(enum ast_bridge_after_cb_reason reason, void *data)
static void after_bridge_move_channel(struct ast_channel *chan_bridged, void *data)
struct ast_channel * chan
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454

◆ bridge_channel_blind_transfer()

static void bridge_channel_blind_transfer ( struct ast_bridge_channel bridge_channel,
struct blind_transfer_data blind_data 
)
static

Definition at line 2016 of file bridge_channel.c.

References ast_async_goto(), ast_bridge_channel_kick(), AST_CAUSE_NORMAL_CLEARING, ast_bridge_channel::chan, blind_transfer_data::context, and blind_transfer_data::exten.

Referenced by bridge_channel_handle_action().

2018 {
2019  ast_async_goto(bridge_channel->chan, blind_data->context, blind_data->exten, 1);
2021 }
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
struct ast_channel * chan
char exten[AST_MAX_EXTENSION]
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:7011
char context[AST_MAX_CONTEXT]

◆ bridge_channel_cancel_owed_events()

static void bridge_channel_cancel_owed_events ( struct ast_bridge_channel bridge_channel)
static

Definition at line 786 of file bridge_channel.c.

References ast_bridge_channel::dtmf_digit, ast_bridge_channel::owed, and ast_bridge_channel::t38_terminate.

Referenced by bridge_channel_internal_push_full().

787 {
788  bridge_channel->owed.dtmf_digit = '\0';
789  bridge_channel->owed.t38_terminate = 0;
790 }
struct ast_bridge_channel::@232 owed

◆ bridge_channel_destroy()

static void bridge_channel_destroy ( void *  obj)
static

Definition at line 3117 of file bridge_channel.c.

References ast_bridge_channel::alert_pipe, ao2_cleanup, ao2_ref, ast_alertpipe_close(), ast_cond_destroy, ast_frfree, AST_LIST_REMOVE_HEAD, AST_VECTOR_FREE, ast_bridge_channel::bridge, bridge_frame_free(), ast_bridge_channel::callid, ast_bridge_channel::cond, ast_bridge_channel::deferred_queue, NULL, ast_bridge_channel::read_format, ast_bridge_channel::stream_map, ast_bridge_channel::to_bridge, ast_bridge_channel::to_channel, ast_bridge_channel::wr_queue, and ast_bridge_channel::write_format.

Referenced by bridge_channel_internal_alloc().

3118 {
3119  struct ast_bridge_channel *bridge_channel = obj;
3120  struct ast_frame *fr;
3121 
3122  if (bridge_channel->callid) {
3123  bridge_channel->callid = 0;
3124  }
3125 
3126  if (bridge_channel->bridge) {
3127  ao2_ref(bridge_channel->bridge, -1);
3128  bridge_channel->bridge = NULL;
3129  }
3130 
3131  /* Flush any unhandled wr_queue frames. */
3132  while ((fr = AST_LIST_REMOVE_HEAD(&bridge_channel->wr_queue, frame_list))) {
3133  bridge_frame_free(fr);
3134  }
3135  ast_alertpipe_close(bridge_channel->alert_pipe);
3136 
3137  /* Flush any unhandled deferred_queue frames. */
3138  while ((fr = AST_LIST_REMOVE_HEAD(&bridge_channel->deferred_queue, frame_list))) {
3139  ast_frfree(fr);
3140  }
3141 
3142  ast_cond_destroy(&bridge_channel->cond);
3143 
3144  ao2_cleanup(bridge_channel->write_format);
3145  ao2_cleanup(bridge_channel->read_format);
3146 
3147  AST_VECTOR_FREE(&bridge_channel->stream_map.to_bridge);
3148  AST_VECTOR_FREE(&bridge_channel->stream_map.to_channel);
3149 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
struct ast_bridge_channel::@230 wr_queue
struct ast_bridge_channel::@236 stream_map
#define NULL
Definition: resample.c:96
struct ast_vector_int to_bridge
struct ast_bridge * bridge
Bridge this channel is participating in.
void ast_alertpipe_close(int alert_pipe[2])
Close an alert pipe.
Definition: alertpipe.c:79
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_format * write_format
struct ast_vector_int to_channel
#define ast_cond_destroy(cond)
Definition: lock.h:200
struct ast_format * read_format
struct ast_bridge_channel::@231 deferred_queue
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_frfree(fr)
Data structure associated with a single frame of data.
static void bridge_frame_free(struct ast_frame *frame)

◆ bridge_channel_dissolve_check()

static void bridge_channel_dissolve_check ( struct ast_bridge_channel bridge_channel)
static

Definition at line 2136 of file bridge_channel.c.

References AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP, ast_bridge_channel_leave_bridge(), AST_BRIDGE_FLAG_DISSOLVE_EMPTY, AST_BRIDGE_FLAG_DISSOLVE_HANGUP, ast_channel_hangupcause(), AST_LIST_FIRST, ast_test_flag, ast_bridge_channel::bridge, BRIDGE_CHANNEL_STATE_END, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_dissolve(), ast_bridge_channel::chan, ast_bridge::channels, ast_bridge::dissolved, ast_bridge_features::feature_flags, ast_bridge::feature_flags, ast_bridge_channel::features, ast_bridge::num_channels, ast_bridge::num_lonely, ast_bridge_channel::state, and ast_bridge_features::usable.

Referenced by bridge_channel_internal_join(), and bridge_channel_internal_pull().

2137 {
2138  struct ast_bridge *bridge = bridge_channel->bridge;
2139 
2140  if (bridge->dissolved) {
2141  return;
2142  }
2143 
2144  if (!bridge->num_channels
2146  /* Last channel leaving the bridge turns off the lights. */
2147  bridge_dissolve(bridge, ast_channel_hangupcause(bridge_channel->chan));
2148  return;
2149  }
2150 
2151  switch (bridge_channel->state) {
2153  /* Do we need to dissolve the bridge because this channel hung up? */
2155  || (bridge_channel->features->usable
2156  && ast_test_flag(&bridge_channel->features->feature_flags,
2158  bridge_dissolve(bridge, ast_channel_hangupcause(bridge_channel->chan));
2159  return;
2160  }
2161  break;
2162  default:
2163  break;
2164  }
2165 
2166  if (bridge->num_lonely && bridge->num_lonely == bridge->num_channels) {
2167  /*
2168  * This will start a chain reaction where each channel leaving
2169  * enters this function and causes the next to leave as long as
2170  * there aren't non-lonely channels in the bridge.
2171  */
2174  ast_channel_hangupcause(bridge_channel->chan));
2175  }
2176 }
struct ast_flags feature_flags
Definition: bridge.h:377
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
struct ast_bridge_features * features
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
unsigned int dissolved
Definition: bridge.h:398
enum bridge_channel_state state
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_flags feature_flags
Structure that contains information about a bridge.
Definition: bridge.h:357
unsigned int num_lonely
Definition: bridge.h:385
struct ast_bridge_channels_list channels
Definition: bridge.h:371
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:319
struct ast_channel * chan
int ast_channel_hangupcause(const struct ast_channel *chan)
unsigned int num_channels
Definition: bridge.h:381

◆ bridge_channel_do_callback()

static void bridge_channel_do_callback ( struct ast_bridge_channel bridge_channel,
struct bridge_custom_callback data 
)
static

Definition at line 1440 of file bridge_channel.c.

References AST_BRIDGE_CHANNEL_CB_OPTION_MEDIA, AST_CONTROL_SRCUPDATE, ast_indicate(), ast_test_flag, bridge_channel_suspend(), bridge_channel_unsuspend(), bridge_custom_callback::callback, ast_bridge_channel::chan, NULL, bridge_custom_callback::payload, bridge_custom_callback::payload_exists, and bridge_custom_callback::payload_size.

Referenced by bridge_channel_handle_action().

1441 {
1443  bridge_channel_suspend(bridge_channel);
1444  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
1445  }
1446  data->callback(bridge_channel, data->payload_exists ? data->payload : NULL, data->payload_size);
1448  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
1449  bridge_channel_unsuspend(bridge_channel);
1450  }
1451 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
#define NULL
Definition: resample.c:96
ast_bridge_custom_callback_fn callback
static void bridge_channel_suspend(struct ast_bridge_channel *bridge_channel)
struct ast_channel * chan
static void bridge_channel_unsuspend(struct ast_bridge_channel *bridge_channel)

◆ bridge_channel_dtmf_stream()

static void bridge_channel_dtmf_stream ( struct ast_bridge_channel bridge_channel,
const char *  dtmf 
)
static

Internal function that plays back DTMF on a bridge channel.

Definition at line 1926 of file bridge_channel.c.

References ast_channel_name(), ast_debug, ast_dtmf_stream(), ast_bridge_channel::chan, and NULL.

Referenced by bridge_channel_handle_action().

1927 {
1928  ast_debug(1, "Playing DTMF stream '%s' out to %p(%s)\n",
1929  dtmf, bridge_channel, ast_channel_name(bridge_channel->chan));
1930  ast_dtmf_stream(bridge_channel->chan, NULL, dtmf, 0, 0);
1931 }
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:981
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)

◆ bridge_channel_event_join_leave()

static void bridge_channel_event_join_leave ( struct ast_bridge_channel bridge_channel,
enum ast_bridge_hook_type  type 
)
static

Definition at line 2872 of file bridge_channel.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ao2_unlink, AST_CONTROL_SRCUPDATE, ast_indicate(), bridge_channel_suspend(), bridge_channel_unsuspend(), ast_bridge_hook::callback, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_hook::hook_pvt, ast_bridge_features::other_hooks, and ast_bridge_hook::type.

Referenced by bridge_channel_internal_join().

2873 {
2874  struct ast_bridge_features *features = bridge_channel->features;
2875  struct ast_bridge_hook *hook;
2876  struct ao2_iterator iter;
2877 
2878  /* Run the specified hooks. */
2879  iter = ao2_iterator_init(features->other_hooks, 0);
2880  for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
2881  if (hook->type == type) {
2882  break;
2883  }
2884  }
2885  if (hook) {
2886  /* Found the first specified hook to run. */
2887  bridge_channel_suspend(bridge_channel);
2888  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2889  do {
2890  if (hook->type == type) {
2891  hook->callback(bridge_channel, hook->hook_pvt);
2892  ao2_unlink(features->other_hooks, hook);
2893  }
2894  ao2_ref(hook, -1);
2895  } while ((hook = ao2_iterator_next(&iter)));
2896  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2897  bridge_channel_unsuspend(bridge_channel);
2898  }
2899  ao2_iterator_destroy(&iter);
2900 }
static const char type[]
Definition: chan_ooh323.c:109
struct ast_bridge_features * features
Structure that contains features information.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
enum ast_bridge_hook_type type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void bridge_channel_suspend(struct ast_bridge_channel *bridge_channel)
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
ast_bridge_hook_callback callback
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ast_channel * chan
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_container * other_hooks
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
Structure that is the essence of a feature hook.
static void bridge_channel_unsuspend(struct ast_bridge_channel *bridge_channel)

◆ bridge_channel_feature_digit_add()

static int bridge_channel_feature_digit_add ( struct ast_bridge_channel bridge_channel,
int  digit,
size_t  dtmf_len 
)
static

Definition at line 1717 of file bridge_channel.c.

References ARRAY_LEN, ast_channel_name(), ast_debug, ast_bridge_channel::chan, ast_bridge_channel::collected, digit, and ast_bridge_channel::dtmf_hook_state.

Referenced by ast_bridge_channel_feature_digit(), and ast_bridge_channel_feature_digit_add().

1719 {
1720  if (dtmf_len < ARRAY_LEN(bridge_channel->dtmf_hook_state.collected) - 1) {
1721  /* Add the new digit to the DTMF string so we can do our matching */
1722  bridge_channel->dtmf_hook_state.collected[dtmf_len++] = digit;
1723  bridge_channel->dtmf_hook_state.collected[dtmf_len] = '\0';
1724 
1725  ast_debug(1, "DTMF feature string on %p(%s) is now '%s'\n",
1726  bridge_channel, ast_channel_name(bridge_channel->chan),
1727  bridge_channel->dtmf_hook_state.collected);
1728  }
1729 
1730  return dtmf_len;
1731 }
char digit
struct ast_bridge_channel::@233 dtmf_hook_state
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char collected[MAXIMUM_DTMF_FEATURE_STRING]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)

◆ bridge_channel_feature_digit_timeout()

static unsigned int bridge_channel_feature_digit_timeout ( struct ast_bridge_channel bridge_channel)
static

Definition at line 1733 of file bridge_channel.c.

References ao2_ref, ast_channel_lock, ast_channel_unlock, ast_get_chan_features_general_config(), ast_log, ast_bridge_channel::chan, ast_features_general_config::featuredigittimeout, and LOG_ERROR.

Referenced by ast_bridge_channel_feature_digit().

1734 {
1735  unsigned int digit_timeout;
1736  struct ast_features_general_config *gen_cfg;
1737 
1738  /* Determine interdigit timeout */
1739  ast_channel_lock(bridge_channel->chan);
1740  gen_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
1741  ast_channel_unlock(bridge_channel->chan);
1742 
1743  if (!gen_cfg) {
1744  ast_log(LOG_ERROR, "Unable to retrieve features configuration.\n");
1745  return 3000; /* Pick a reasonable failsafe timeout in ms */
1746  }
1747 
1748  digit_timeout = gen_cfg->featuredigittimeout;
1749  ao2_ref(gen_cfg, -1);
1750 
1751  return digit_timeout;
1752 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
General features configuration items.
struct ast_features_general_config * ast_get_chan_features_general_config(struct ast_channel *chan)
Get the general configuration options for a channel.
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan

◆ bridge_channel_feature_timeout()

static int bridge_channel_feature_timeout ( struct ast_bridge_channel bridge_channel)
static

Definition at line 2753 of file bridge_channel.c.

References ast_tvdiff_ms(), ast_tvnow(), ast_bridge_channel::collected, ast_bridge_channel::dtmf_hook_state, and ast_bridge_channel::interdigit_timeout.

Referenced by bridge_channel_next_timeout().

2754 {
2755  int ms;
2756 
2757  if (bridge_channel->dtmf_hook_state.collected[0]) {
2758  ms = ast_tvdiff_ms(bridge_channel->dtmf_hook_state.interdigit_timeout,
2759  ast_tvnow());
2760  if (ms < 0) {
2761  /* Expire immediately. */
2762  ms = 0;
2763  }
2764  } else {
2765  /* Timer is not active so wait forever. */
2766  ms = -1;
2767  }
2768 
2769  return ms;
2770 }
struct ast_bridge_channel::@233 dtmf_hook_state
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
char collected[MAXIMUM_DTMF_FEATURE_STRING]
struct timeval interdigit_timeout

◆ bridge_channel_handle_action()

static void bridge_channel_handle_action ( struct ast_bridge_channel bridge_channel,
enum bridge_channel_action_type  action,
void *  data 
)
static

Definition at line 2067 of file bridge_channel.c.

References ast_bridge_channel_kick(), ast_check_hangup_locked(), AST_CONTROL_SRCUPDATE, ast_indicate(), BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, BRIDGE_CHANNEL_ACTION_CALLBACK, BRIDGE_CHANNEL_ACTION_DTMF_STREAM, BRIDGE_CHANNEL_ACTION_PARK, BRIDGE_CHANNEL_ACTION_PLAY_FILE, BRIDGE_CHANNEL_ACTION_RUN_APP, BRIDGE_CHANNEL_ACTION_TALKING_START, BRIDGE_CHANNEL_ACTION_TALKING_STOP, bridge_channel_attended_transfer(), bridge_channel_blind_transfer(), bridge_channel_do_callback(), bridge_channel_dtmf_stream(), bridge_channel_park(), bridge_channel_playfile(), bridge_channel_run_app(), bridge_channel_suspend(), bridge_channel_talking(), bridge_channel_unsuspend(), and ast_bridge_channel::chan.

Referenced by bridge_channel_handle_write().

2069 {
2070  switch (action) {
2072  bridge_channel_suspend(bridge_channel);
2073  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2074  bridge_channel_dtmf_stream(bridge_channel, data);
2075  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2076  bridge_channel_unsuspend(bridge_channel);
2077  break;
2080  bridge_channel_talking(bridge_channel,
2082  break;
2084  bridge_channel_suspend(bridge_channel);
2085  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2086  bridge_channel_playfile(bridge_channel, data);
2087  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2088  bridge_channel_unsuspend(bridge_channel);
2089  break;
2091  bridge_channel_suspend(bridge_channel);
2092  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2093  bridge_channel_run_app(bridge_channel, data);
2094  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2095  bridge_channel_unsuspend(bridge_channel);
2096  break;
2098  bridge_channel_do_callback(bridge_channel, data);
2099  break;
2101  bridge_channel_suspend(bridge_channel);
2102  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2103  bridge_channel_park(bridge_channel, data);
2104  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
2105  bridge_channel_unsuspend(bridge_channel);
2106  break;
2108  bridge_channel_blind_transfer(bridge_channel, data);
2109  break;
2111  bridge_channel_attended_transfer(bridge_channel, data);
2112  break;
2113  default:
2114  break;
2115  }
2116 
2117  /* While invoking an action it is possible for the channel to be hung up. So
2118  * that the bridge respects this we check here and if hung up kick it out.
2119  */
2120  if (bridge_channel->chan && ast_check_hangup_locked(bridge_channel->chan)) {
2121  ast_bridge_channel_kick(bridge_channel, 0);
2122  }
2123 }
static void bridge_channel_blind_transfer(struct ast_bridge_channel *bridge_channel, struct blind_transfer_data *blind_data)
static void bridge_channel_do_callback(struct ast_bridge_channel *bridge_channel, struct bridge_custom_callback *data)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
static void bridge_channel_run_app(struct ast_bridge_channel *bridge_channel, struct bridge_run_app *data)
static void bridge_channel_talking(struct ast_bridge_channel *bridge_channel, int talking)
static void bridge_channel_dtmf_stream(struct ast_bridge_channel *bridge_channel, const char *dtmf)
Internal function that plays back DTMF on a bridge channel.
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
static void bridge_channel_suspend(struct ast_bridge_channel *bridge_channel)
static void bridge_channel_attended_transfer(struct ast_bridge_channel *bridge_channel, const char *target_chan_name)
struct ast_channel * chan
static void bridge_channel_park(struct ast_bridge_channel *bridge_channel, struct bridge_park *payload)
static void bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, struct bridge_playfile *payload)
static void bridge_channel_unsuspend(struct ast_bridge_channel *bridge_channel)

◆ bridge_channel_handle_control()

static void bridge_channel_handle_control ( struct ast_bridge_channel bridge_channel,
struct ast_frame fr 
)
static

Definition at line 2330 of file bridge_channel.c.

References ast_answer(), ast_assert, ast_bridge_channel_lock_bridge(), ast_bridge_unlock, ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_flags(), ast_channel_redirecting_macro(), ast_channel_redirecting_sub(), ast_channel_setoption(), AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_OPTION, AST_CONTROL_REDIRECTING, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, AST_FLAG_OUTGOING, ast_indicate(), ast_indicate_data(), AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_RELAXDTMF, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_STATE_UP, ast_test_flag, ast_bridge_channel::bridge, bridge_reconfigured(), ast_bridge_channel::chan, ast_frame::data, ast_option_header::data, ast_frame::datalen, ast_frame_subclass::integer, NULL, ast_frame::ptr, ast_bridge::reconfigured, and ast_frame::subclass.

Referenced by bridge_channel_handle_write().

2331 {
2332  struct ast_channel *chan;
2333  struct ast_option_header *aoh;
2334  int is_caller;
2335 
2336  chan = bridge_channel->chan;
2337  switch (fr->subclass.integer) {
2339  is_caller = !ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
2340  if (ast_channel_redirecting_sub(NULL, chan, fr, 1) &&
2341  ast_channel_redirecting_macro(NULL, chan, fr, is_caller, 1)) {
2342  ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
2343  }
2344  break;
2346  is_caller = !ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
2347  if (ast_channel_connected_line_sub(NULL, chan, fr, 1) &&
2348  ast_channel_connected_line_macro(NULL, chan, fr, is_caller, 1)) {
2349  ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
2350  }
2351  break;
2352  case AST_CONTROL_OPTION:
2353  /*
2354  * Forward option Requests, but only ones we know are safe These
2355  * are ONLY sent by chan_iax2 and I'm not convinced that they
2356  * are useful. I haven't deleted them entirely because I just am
2357  * not sure of the ramifications of removing them.
2358  */
2359  aoh = fr->data.ptr;
2360  if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
2361  switch (ntohs(aoh->option)) {
2363  case AST_OPTION_TDD:
2364  case AST_OPTION_RELAXDTMF:
2365  case AST_OPTION_AUDIO_MODE:
2367  case AST_OPTION_FAX_DETECT:
2368  ast_channel_setoption(chan, ntohs(aoh->option), aoh->data,
2369  fr->datalen - sizeof(*aoh), 0);
2370  break;
2371  default:
2372  break;
2373  }
2374  }
2375  break;
2376  case AST_CONTROL_ANSWER:
2377  if (ast_channel_state(chan) != AST_STATE_UP) {
2378  ast_answer(chan);
2379  ast_bridge_channel_lock_bridge(bridge_channel);
2380  bridge_channel->bridge->reconfigured = 1;
2381  bridge_reconfigured(bridge_channel->bridge, 0);
2382  ast_bridge_unlock(bridge_channel->bridge);
2383  } else {
2384  ast_indicate(chan, -1);
2385  }
2386  break;
2388  /* Should never happen. */
2389  ast_assert(0);
2390  break;
2392  ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
2393  break;
2394  default:
2395  ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
2396  break;
2397  }
2398 }
Main Channel structure associated with a channel.
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:10435
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
unsigned int reconfigured
Definition: bridge.h:396
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4698
#define ast_assert(a)
Definition: utils.h:695
#define AST_OPTION_TDD
#define NULL
Definition: resample.c:96
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7522
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_frame_subclass subclass
#define AST_OPTION_RELAXDTMF
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1443
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel&#39;s redirecting information.
Definition: channel.c:10584
#define AST_OPTION_DIGIT_DETECT
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel&#39;s connected line information...
Definition: channel.c:10539
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define AST_OPTION_AUDIO_MODE
struct ast_channel * chan
#define AST_OPTION_FAX_DETECT
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
#define AST_OPTION_FLAG_REQUEST
#define AST_OPTION_TONE_VERIFY
union ast_frame::@263 data
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
Run a redirecting interception macro and update a channel&#39;s redirecting information.
Definition: channel.c:10487

◆ bridge_channel_handle_feature_timeout()

static void bridge_channel_handle_feature_timeout ( struct ast_bridge_channel bridge_channel)
static

Definition at line 1883 of file bridge_channel.c.

References ast_bridge_channel_feature_digit(), ast_tvdiff_ms(), ast_tvnow(), ast_bridge_channel::collected, ast_bridge_channel::dtmf_hook_state, and ast_bridge_channel::interdigit_timeout.

Referenced by bridge_channel_wait().

1884 {
1885  if (!bridge_channel->dtmf_hook_state.collected[0]
1886  || 0 < ast_tvdiff_ms(bridge_channel->dtmf_hook_state.interdigit_timeout,
1887  ast_tvnow())) {
1888  /* Not within a sequence or not timed out. */
1889  return;
1890  }
1891 
1892  ast_bridge_channel_feature_digit(bridge_channel, 0);
1893 }
struct ast_bridge_channel::@233 dtmf_hook_state
void ast_bridge_channel_feature_digit(struct ast_bridge_channel *bridge_channel, int digit)
Add a DTMF digit to the collected digits to match against DTMF features.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
char collected[MAXIMUM_DTMF_FEATURE_STRING]
struct timeval interdigit_timeout

◆ bridge_channel_handle_interval()

static void bridge_channel_handle_interval ( struct ast_bridge_channel bridge_channel)
static

Definition at line 1570 of file bridge_channel.c.

References ao2_ref, ast_atomic_fetchadd_int(), AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA, ast_channel_name(), AST_CONTROL_SRCUPDATE, ast_debug, ast_heap_peek(), ast_heap_push, ast_heap_remove(), ast_heap_unlock, ast_heap_wrlock, ast_indicate(), ast_samp2tv(), ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), bridge_channel_suspend(), bridge_channel_unsuspend(), ast_bridge_hook::callback, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_hook_timer::generic, ast_bridge_hook_timer_parms::heap_index, ast_bridge_hook::hook_pvt, ast_bridge_hook_timer_parms::interval, ast_bridge_features::interval_hooks, ast_bridge_features::interval_sequence, ast_bridge_hook_timer_parms::seqno, ast_bridge_hook_timer::timer, and ast_bridge_hook_timer_parms::trip_time.

Referenced by bridge_channel_wait().

1571 {
1572  struct ast_heap *interval_hooks;
1573  struct ast_bridge_hook_timer *hook;
1574  struct timeval start;
1575  int chan_suspended = 0;
1576 
1577  interval_hooks = bridge_channel->features->interval_hooks;
1578  ast_heap_wrlock(interval_hooks);
1579  start = ast_tvnow();
1580  while ((hook = ast_heap_peek(interval_hooks, 1))) {
1581  int interval;
1582  unsigned int execution_time;
1583 
1584  if (ast_tvdiff_ms(hook->timer.trip_time, start) > 0) {
1585  ast_debug(1, "Hook %p on %p(%s) wants to happen in the future, stopping our traversal\n",
1586  hook, bridge_channel, ast_channel_name(bridge_channel->chan));
1587  break;
1588  }
1589  ao2_ref(hook, +1);
1590  ast_heap_unlock(interval_hooks);
1591 
1592  if (!chan_suspended
1594  chan_suspended = 1;
1595  bridge_channel_suspend(bridge_channel);
1596  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
1597  }
1598 
1599  ast_debug(1, "Executing hook %p on %p(%s)\n",
1600  hook, bridge_channel, ast_channel_name(bridge_channel->chan));
1601  interval = hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
1602 
1603  ast_heap_wrlock(interval_hooks);
1604  if (ast_heap_peek(interval_hooks, hook->timer.heap_index) != hook
1605  || !ast_heap_remove(interval_hooks, hook)) {
1606  /* Interval hook is already removed from the bridge_channel. */
1607  ao2_ref(hook, -1);
1608  continue;
1609  }
1610  ao2_ref(hook, -1);
1611 
1612  if (interval < 0) {
1613  ast_debug(1, "Removed interval hook %p from %p(%s)\n",
1614  hook, bridge_channel, ast_channel_name(bridge_channel->chan));
1615  ao2_ref(hook, -1);
1616  continue;
1617  }
1618  if (interval) {
1619  /* Set new interval for the hook. */
1620  hook->timer.interval = interval;
1621  }
1622 
1623  ast_debug(1, "Updating interval hook %p with interval %u on %p(%s)\n",
1624  hook, hook->timer.interval, bridge_channel,
1625  ast_channel_name(bridge_channel->chan));
1626 
1627  /* resetting start */
1628  start = ast_tvnow();
1629 
1630  /*
1631  * Resetup the interval hook for the next interval. We may need
1632  * to skip over any missed intervals because the hook was
1633  * delayed or took too long.
1634  */
1635  execution_time = ast_tvdiff_ms(start, hook->timer.trip_time);
1636  while (hook->timer.interval < execution_time) {
1637  execution_time -= hook->timer.interval;
1638  }
1639  hook->timer.trip_time = ast_tvadd(start, ast_samp2tv(hook->timer.interval - execution_time, 1000));
1640  hook->timer.seqno = ast_atomic_fetchadd_int((int *) &bridge_channel->features->interval_sequence, +1);
1641 
1642  if (ast_heap_push(interval_hooks, hook)) {
1643  /* Could not push the hook back onto the heap. */
1644  ao2_ref(hook, -1);
1645  }
1646  }
1647  ast_heap_unlock(interval_hooks);
1648 
1649  if (chan_suspended) {
1650  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
1651  bridge_channel_unsuspend(bridge_channel);
1652  }
1653 }
struct ast_bridge_features * features
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
#define ast_heap_unlock(h)
Definition: heap.h:248
struct ast_bridge_hook generic
Definition: heap.c:36
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_heap_push(h, elm)
Definition: heap.h:126
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
struct ast_heap * interval_hooks
static void bridge_channel_suspend(struct ast_bridge_channel *bridge_channel)
ast_bridge_hook_callback callback
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
struct ast_bridge_hook_timer_parms timer
struct ast_channel * chan
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition: heap.c:251
const char * ast_channel_name(const struct ast_channel *chan)
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
unsigned int interval_sequence
static void bridge_channel_unsuspend(struct ast_bridge_channel *bridge_channel)
#define ast_heap_wrlock(h)
Definition: heap.h:246

◆ bridge_channel_handle_write()

static void bridge_channel_handle_write ( struct ast_bridge_channel bridge_channel)
static

Definition at line 2444 of file bridge_channel.c.

References ast_bridge_channel::activity, ast_bridge_channel::alert_pipe, ast_alertpipe_read(), ast_assert, ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_channel_name(), ast_debug, AST_FRAME_BRIDGE_ACTION, AST_FRAME_BRIDGE_ACTION_SYNC, AST_FRAME_CONTROL, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_TEXT_DATA, AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, AST_MSG_DATA_ATTR_BODY, AST_MSG_DATA_ATTR_FROM, AST_MSG_DATA_ATTR_TO, ast_msg_data_get_attribute(), ast_sendtext_data(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_write_stream(), bridge_channel_handle_action(), bridge_channel_handle_control(), BRIDGE_CHANNEL_THREAD_SIMPLE, bridge_frame_free(), ast_bridge_channel::chan, ast_bridge_channel::collected, sync_payload::data, ast_frame::data, ast_frame::datalen, ast_bridge_channel::dtmf_hook_state, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::ptr, sendtext_safe(), ast_bridge_channel::stream_map, ast_frame::stream_num, ast_frame::subclass, ast_bridge_channel::to_channel, and ast_bridge_channel::wr_queue.

Referenced by bridge_channel_wait().

2445 {
2446  struct ast_frame *fr;
2447  struct sync_payload *sync_payload;
2448  int num;
2449  struct ast_msg_data *msg;
2450 
2451  ast_bridge_channel_lock(bridge_channel);
2452 
2453  /* It's not good to have unbalanced frames and alert_pipe alerts. */
2454  ast_assert(!AST_LIST_EMPTY(&bridge_channel->wr_queue));
2455  if (AST_LIST_EMPTY(&bridge_channel->wr_queue)) {
2456  /* No frame, flush the alert pipe of excess alerts. */
2457  ast_log(LOG_WARNING, "Weird. No frame from bridge for %s to process?\n",
2458  ast_channel_name(bridge_channel->chan));
2459  ast_alertpipe_read(bridge_channel->alert_pipe);
2460  ast_bridge_channel_unlock(bridge_channel);
2461  return;
2462  }
2463 
2464  AST_LIST_TRAVERSE_SAFE_BEGIN(&bridge_channel->wr_queue, fr, frame_list) {
2465  if (bridge_channel->dtmf_hook_state.collected[0]) {
2466  switch (fr->frametype) {
2469  /* Defer processing these frames while DTMF is collected. */
2470  continue;
2471  default:
2472  break;
2473  }
2474  }
2475  ast_alertpipe_read(bridge_channel->alert_pipe);
2477  break;
2478  }
2480 
2481  ast_bridge_channel_unlock(bridge_channel);
2482 
2483  if (!fr) {
2484  /*
2485  * Wait some to reduce CPU usage from a tight loop
2486  * without any wait because we only have deferred
2487  * frames in the wr_queue.
2488  */
2489  usleep(1);
2490  return;
2491  }
2492 
2493  switch (fr->frametype) {
2495  bridge_channel_handle_action(bridge_channel, fr->subclass.integer, fr->data.ptr);
2496  break;
2498  sync_payload = fr->data.ptr;
2499  bridge_channel_handle_action(bridge_channel, fr->subclass.integer, sync_payload->data);
2500  break;
2501  case AST_FRAME_CONTROL:
2502  bridge_channel_handle_control(bridge_channel, fr);
2503  break;
2504  case AST_FRAME_NULL:
2505  break;
2506  case AST_FRAME_TEXT:
2507  ast_debug(1, "Sending TEXT frame to '%s': %*.s\n",
2508  ast_channel_name(bridge_channel->chan), fr->datalen, (char *)fr->data.ptr);
2509  sendtext_safe(bridge_channel->chan, fr);
2510  break;
2511  case AST_FRAME_TEXT_DATA:
2512  msg = (struct ast_msg_data *)fr->data.ptr;
2513  ast_debug(1, "Sending TEXT_DATA frame from '%s' to '%s:%s': %s\n",
2516  ast_channel_name(bridge_channel->chan),
2518  ast_sendtext_data(bridge_channel->chan, msg);
2519  break;
2520  default:
2521  /* Assume that there is no mapped stream for this */
2522  num = -1;
2523 
2524  if (fr->stream_num > -1) {
2525  ast_bridge_channel_lock(bridge_channel);
2526  if (fr->stream_num < (int)AST_VECTOR_SIZE(&bridge_channel->stream_map.to_channel)) {
2527  num = AST_VECTOR_GET(&bridge_channel->stream_map.to_channel, fr->stream_num);
2528  }
2529  ast_bridge_channel_unlock(bridge_channel);
2530 
2531  /* If there is no mapped stream after checking the mapping then there is nowhere
2532  * to write this frame to, so drop it.
2533  */
2534  if (num == -1) {
2535  break;
2536  }
2537  }
2538 
2539  /* Write the frame to the channel. */
2540  bridge_channel->activity = BRIDGE_CHANNEL_THREAD_SIMPLE;
2541  ast_write_stream(bridge_channel->chan, num, fr);
2542  break;
2543  }
2544  bridge_frame_free(fr);
2545 }
static void bridge_channel_handle_control(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
enum bridge_channel_thread_state activity
The bridge channel thread activity.
struct ast_bridge_channel::@233 dtmf_hook_state
struct ast_bridge_channel::@230 wr_queue
#define LOG_WARNING
Definition: logger.h:274
static void sendtext_safe(struct ast_channel *chan, const struct ast_frame *f)
Structure used to transport a message through the frame core.
Definition: message.c:1406
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_assert(a)
Definition: utils.h:695
int ast_sendtext_data(struct ast_channel *chan, struct ast_msg_data *msg)
Sends text to a channel in an ast_msg_data structure wrapper with ast_sendtext as fallback...
Definition: channel.c:4796
struct ast_bridge_channel::@236 stream_map
char collected[MAXIMUM_DTMF_FEATURE_STRING]
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
int ast_write_stream(struct ast_channel *chan, int stream_num, struct ast_frame *frame)
Write a frame to a stream This function writes the given frame to the indicated stream on the channel...
Definition: channel.c:5194
struct ast_frame_subclass subclass
Frame payload for synchronous bridge actions.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
struct ast_vector_int to_channel
ast_alert_status_t ast_alertpipe_read(int alert_pipe[2])
Read an event from an alert pipe.
Definition: alertpipe.c:102
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
Definition: message.c:1533
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
Data structure associated with a single frame of data.
union ast_frame::@263 data
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
enum ast_frame_type frametype
static void bridge_frame_free(struct ast_frame *frame)
static void bridge_channel_handle_action(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, void *data)
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
unsigned char data[0]

◆ bridge_channel_internal_alloc()

struct ast_bridge_channel* bridge_channel_internal_alloc ( struct ast_bridge bridge)

Definition at line 3151 of file bridge_channel.c.

References ast_bridge_channel::alert_pipe, ao2_alloc, ao2_ref, ast_alertpipe_init(), ast_cond_init, ast_bridge_channel::bridge, bridge_channel_destroy(), ast_bridge_channel::cond, and NULL.

Referenced by ast_bridge_join(), and bridge_impart_internal().

3152 {
3153  struct ast_bridge_channel *bridge_channel;
3154 
3155  bridge_channel = ao2_alloc(sizeof(struct ast_bridge_channel), bridge_channel_destroy);
3156  if (!bridge_channel) {
3157  return NULL;
3158  }
3159  ast_cond_init(&bridge_channel->cond, NULL);
3160  if (ast_alertpipe_init(bridge_channel->alert_pipe)) {
3161  ao2_ref(bridge_channel, -1);
3162  return NULL;
3163  }
3164  if (bridge) {
3165  bridge_channel->bridge = bridge;
3166  ao2_ref(bridge_channel->bridge, +1);
3167  }
3168 
3169  /* The stream_map is initialized later - see ast_bridge_channel_stream_map */
3170 
3171  return bridge_channel;
3172 }
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_alertpipe_init(int alert_pipe[2])
Initialize an alert pipe.
Definition: alertpipe.c:38
static void bridge_channel_destroy(void *obj)
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
Structure that contains information regarding a channel in a bridge.

◆ bridge_channel_internal_allows_optimization()

int bridge_channel_internal_allows_optimization ( struct ast_bridge_channel bridge_channel)

Definition at line 3110 of file bridge_channel.c.

References AST_LIST_EMPTY, ast_bridge_channel::in_bridge, and ast_bridge_channel::wr_queue.

Referenced by optimize_lock_chan_stack(), and optimize_lock_peer_stack().

3111 {
3112  return bridge_channel->in_bridge
3113  && AST_LIST_EMPTY(&bridge_channel->wr_queue);
3114 }
struct ast_bridge_channel::@230 wr_queue
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
unsigned int in_bridge

◆ bridge_channel_internal_join()

int bridge_channel_internal_join ( struct ast_bridge_channel bridge_channel)

Definition at line 2902 of file bridge_channel.c.

References ao2_bump, ao2_t_cleanup, AST_BRIDGE_CAPABILITY_MULTIMIX, ast_bridge_channel_feature_digit(), ast_bridge_channel_kick(), ast_bridge_channel_lock_bridge(), ast_bridge_channel_restore_formats(), ast_bridge_features_merge(), ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, AST_BRIDGE_HOOK_TYPE_JOIN, AST_BRIDGE_HOOK_TYPE_LEAVE, ast_bridge_lock, ast_bridge_remove_video_src(), ast_bridge_unlock, ast_channel_end_dtmf(), ast_channel_feature_hooks_get(), ast_channel_flags(), ast_channel_hold_state(), ast_channel_internal_bridge(), ast_channel_internal_bridge_set(), ast_channel_is_t38_active(), ast_channel_lock, ast_channel_name(), ast_channel_readformat(), ast_channel_sending_dtmf_digit(), ast_channel_sending_dtmf_tv(), ast_channel_unlock, ast_channel_writeformat(), AST_CONTROL_HOLD, AST_CONTROL_SRCCHANGE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, ast_debug, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT, AST_FLAG_ZOMBIE, ast_indicate(), ast_indicate_data(), ast_jb_enable_for_channel(), ast_read_threadstorage_callid(), AST_T38_TERMINATED, ast_test_flag, ast_bridge_channel::bridge, bridge_channel_dissolve_check(), bridge_channel_event_join_leave(), bridge_channel_impart_signal(), bridge_channel_internal_pull(), bridge_channel_internal_push(), bridge_channel_settle_owed_events(), BRIDGE_CHANNEL_STATE_WAIT, bridge_channel_wait(), bridge_reconfigured(), ast_bridge::callid, ast_bridge_technology::capabilities, ast_bridge::cause, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_channel::inhibit_colp, NULL, ast_bridge_channel::read_format, ast_control_t38_parameters::request_response, ast_bridge_channel::state, ast_bridge_channel::swap, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge_channel::write_format.

Referenced by ast_bridge_join(), bridge_channel_depart_thread(), and bridge_channel_ind_thread().

2903 {
2904  int res = 0;
2905  uint8_t indicate_src_change = 0;
2906  struct ast_bridge_features *channel_features;
2907  struct ast_channel *swap;
2908 
2909  ast_debug(1, "Bridge %s: %p(%s) is joining\n",
2910  bridge_channel->bridge->uniqueid,
2911  bridge_channel, ast_channel_name(bridge_channel->chan));
2912 
2913  /*
2914  * Directly locking the bridge is safe here because nobody else
2915  * knows about this bridge_channel yet.
2916  */
2917  ast_bridge_lock(bridge_channel->bridge);
2918 
2919  ast_channel_lock(bridge_channel->chan);
2920 
2921  bridge_channel->read_format = ao2_bump(ast_channel_readformat(bridge_channel->chan));
2922  bridge_channel->write_format = ao2_bump(ast_channel_writeformat(bridge_channel->chan));
2923 
2924  /* Make sure we're still good to be put into a bridge */
2925  if (ast_channel_internal_bridge(bridge_channel->chan)
2926  || ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_ZOMBIE)) {
2927  ast_channel_unlock(bridge_channel->chan);
2928  ast_bridge_unlock(bridge_channel->bridge);
2929  ast_debug(1, "Bridge %s: %p(%s) failed to join Bridge\n",
2930  bridge_channel->bridge->uniqueid,
2931  bridge_channel,
2932  ast_channel_name(bridge_channel->chan));
2933  return -1;
2934  }
2935  ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
2936 
2937  /* Attach features requested by the channel */
2938  channel_features = ast_channel_feature_hooks_get(bridge_channel->chan);
2939  if (channel_features) {
2940  ast_bridge_features_merge(bridge_channel->features, channel_features);
2941  }
2942  ast_channel_unlock(bridge_channel->chan);
2943 
2944  /* Add the jitterbuffer if the channel requires it */
2945  ast_jb_enable_for_channel(bridge_channel->chan);
2946 
2947  if (!bridge_channel->bridge->callid) {
2948  bridge_channel->bridge->callid = ast_read_threadstorage_callid();
2949  }
2950 
2951  /* Take the swap channel ref from the bridge_channel struct. */
2952  swap = bridge_channel->swap;
2953 
2954  if (bridge_channel_internal_push(bridge_channel)) {
2955  int cause = bridge_channel->bridge->cause;
2956 
2957  ast_bridge_unlock(bridge_channel->bridge);
2958  ast_bridge_channel_kick(bridge_channel, cause);
2959  ast_bridge_channel_lock_bridge(bridge_channel);
2960  ast_bridge_features_remove(bridge_channel->features,
2962  bridge_channel_dissolve_check(bridge_channel);
2963  res = -1;
2964  }
2965  bridge_reconfigured(bridge_channel->bridge, !bridge_channel->inhibit_colp);
2966 
2967  if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2968  /*
2969  * Indicate a source change since this channel is entering the
2970  * bridge system only if the bridge technology is not MULTIMIX
2971  * capable. The MULTIMIX technology has already done it.
2972  */
2973  if (!(bridge_channel->bridge->technology->capabilities
2975  indicate_src_change = 1;
2976  }
2977 
2978  bridge_channel_impart_signal(bridge_channel->chan);
2979  ast_bridge_unlock(bridge_channel->bridge);
2980 
2981  /* Must release any swap ref after unlocking the bridge. */
2982  ao2_t_cleanup(swap, "Bridge push with swap successful");
2983  swap = NULL;
2984 
2985  if (indicate_src_change) {
2986  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
2987  }
2988 
2990 
2991  while (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2992  /* Wait for something to do. */
2993  bridge_channel_wait(bridge_channel);
2994  }
2995 
2996  /* Force a timeout on any accumulated DTMF hook digits. */
2997  ast_bridge_channel_feature_digit(bridge_channel, 0);
2998 
3000  ast_bridge_channel_lock_bridge(bridge_channel);
3001  }
3002 
3003  bridge_channel_internal_pull(bridge_channel);
3004  bridge_channel_settle_owed_events(bridge_channel->bridge, bridge_channel);
3005  bridge_reconfigured(bridge_channel->bridge, 1);
3006 
3007  /* Remove ourselves if we are the video source */
3008  ast_bridge_remove_video_src(bridge_channel->bridge, bridge_channel->chan);
3009 
3010  ast_bridge_unlock(bridge_channel->bridge);
3011 
3012  /* Must release any swap ref after unlocking the bridge. */
3013  ao2_t_cleanup(swap, "Bridge push with swap failed or exited immediately");
3014 
3015  /* Complete any active hold before exiting the bridge. */
3016  if (ast_channel_hold_state(bridge_channel->chan) == AST_CONTROL_HOLD) {
3017  ast_debug(1, "Channel %s simulating UNHOLD for bridge end.\n",
3018  ast_channel_name(bridge_channel->chan));
3019  ast_indicate(bridge_channel->chan, AST_CONTROL_UNHOLD);
3020  }
3021 
3022  /* Complete any partial DTMF digit before exiting the bridge. */
3023  if (ast_channel_sending_dtmf_digit(bridge_channel->chan)) {
3024  ast_channel_end_dtmf(bridge_channel->chan,
3025  ast_channel_sending_dtmf_digit(bridge_channel->chan),
3026  ast_channel_sending_dtmf_tv(bridge_channel->chan), "bridge end");
3027  }
3028 
3029  /* Complete any T.38 session before exiting the bridge. */
3030  if (ast_channel_is_t38_active(bridge_channel->chan)) {
3031  struct ast_control_t38_parameters t38_parameters = {
3033  };
3034 
3035  ast_debug(1, "Channel %s simulating T.38 terminate for bridge end.\n",
3036  ast_channel_name(bridge_channel->chan));
3038  &t38_parameters, sizeof(t38_parameters));
3039  }
3040 
3041  /* Indicate a source change since this channel is leaving the bridge system. */
3042  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
3043 
3044  /*
3045  * Wait for any dual redirect to complete.
3046  *
3047  * Must be done while "still in the bridge" for ast_async_goto()
3048  * to work right.
3049  */
3051  sched_yield();
3052  }
3053  ast_channel_lock(bridge_channel->chan);
3054  ast_channel_internal_bridge_set(bridge_channel->chan, NULL);
3055  ast_channel_unlock(bridge_channel->chan);
3056 
3057  ast_bridge_channel_restore_formats(bridge_channel);
3058 
3059  return res;
3060 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1959
int ast_channel_hold_state(const struct ast_channel *chan)
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
static void bridge_channel_wait(struct ast_bridge_channel *bridge_channel)
Structure that contains features information.
int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
#define ast_test_flag(p, flag)
Definition: utils.h:63
char ast_channel_sending_dtmf_digit(const struct ast_channel *chan)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
ast_callid callid
Definition: bridge.h:369
void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel)
Restore the formats of a bridge channel&#39;s channel to how they were before bridge_channel_internal_joi...
enum bridge_channel_state state
enum ast_control_t38 request_response
static void bridge_channel_event_join_leave(struct ast_bridge_channel *bridge_channel, enum ast_bridge_hook_type type)
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4698
static void bridge_channel_dissolve_check(struct ast_bridge_channel *bridge_channel)
void ast_bridge_channel_feature_digit(struct ast_bridge_channel *bridge_channel, int digit)
Add a DTMF digit to the collected digits to match against DTMF features.
struct ast_bridge * ast_channel_internal_bridge(const struct ast_channel *chan)
#define NULL
Definition: resample.c:96
struct ast_bridge * bridge
Bridge this channel is participating in.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:1962
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_bridge_technology * technology
Definition: bridge.h:363
void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
remove a channel as a source of video for the bridge.
Definition: bridge.c:3984
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void ast_jb_enable_for_channel(struct ast_channel *chan)
Sets a jitterbuffer frame hook on the channel based on the channel&#39;s stored jitterbuffer configuratio...
Definition: abstract_jb.c:585
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1443
int ast_channel_is_t38_active(struct ast_channel *chan)
This function will check if T.38 is active on the channel.
struct ast_format * write_format
void ast_bridge_features_merge(struct ast_bridge_features *into, const struct ast_bridge_features *from)
Merge one ast_bridge_features into another.
Definition: bridge.c:3662
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
struct ast_format * read_format
struct ast_bridge_features * ast_channel_feature_hooks_get(struct ast_channel *chan)
Gets the channel-attached features a channel has access to upon being bridged.
Definition: channel.c:11104
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
unsigned int inhibit_colp
void ast_channel_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why)
Simulate a DTMF end on a broken bridge channel.
Definition: channel.c:11070
struct ast_channel * swap
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:3568
int cause
Definition: bridge.h:394
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
struct timeval ast_channel_sending_dtmf_tv(const struct ast_channel *chan)
struct ast_channel * chan
void bridge_channel_impart_signal(struct ast_channel *chan)
Signal imparting threads to wake up.
Definition: bridge.c:1626
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.

◆ bridge_channel_internal_pull()

void bridge_channel_internal_pull ( struct ast_bridge_channel bridge_channel)

Definition at line 2178 of file bridge_channel.c.

References ast_bridge_channel_clear_roles(), AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_bridge_publish_leave(), ast_channel_clear_flag(), ast_channel_flags(), ast_channel_is_leaving_bridge(), ast_channel_name(), ast_debug, AST_FLAG_OUTGOING, AST_LIST_REMOVE, ast_test_flag, ast_verb, ast_bridge_channel::bridge, bridge_channel_dissolve_check(), BRIDGE_CHANNEL_STATE_WAIT, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge_channel::in_bridge, ast_bridge_channel::just_joined, ast_bridge_technology::leave, ast_bridge_technology::name, ast_bridge_methods::name, ast_bridge::num_active, ast_bridge::num_channels, ast_bridge::num_lonely, ast_bridge_methods::pull, ast_bridge::reconfigured, ast_bridge_channel::state, ast_bridge_channel::suspended, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by bridge_channel_internal_join(), bridge_channel_internal_push_full(), bridge_do_merge(), and bridge_do_move().

2179 {
2180  struct ast_bridge *bridge = bridge_channel->bridge;
2181 
2182  if (!bridge_channel->in_bridge) {
2183  return;
2184  }
2185  bridge_channel->in_bridge = 0;
2186 
2187  ast_debug(1, "Bridge %s: pulling %p(%s)\n",
2188  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2189 
2190  ast_verb(3, "Channel %s left '%s' %s-bridge <%s>\n",
2191  ast_channel_name(bridge_channel->chan),
2192  bridge->technology->name,
2193  bridge->v_table->name,
2194  bridge->uniqueid);
2195 
2196  if (!bridge_channel->just_joined) {
2197  /* Tell the bridge technology we are leaving so they tear us down */
2198  ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology\n",
2199  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
2200  bridge->technology->name);
2201  if (bridge->technology->leave) {
2202  bridge->technology->leave(bridge, bridge_channel);
2203  }
2204  }
2205 
2206  /* Remove channel from the bridge */
2207  if (!bridge_channel->suspended) {
2208  --bridge->num_active;
2209  }
2211  --bridge->num_lonely;
2212  }
2213  --bridge->num_channels;
2214  AST_LIST_REMOVE(&bridge->channels, bridge_channel, entry);
2215 
2216  bridge_channel_dissolve_check(bridge_channel);
2217  bridge->v_table->pull(bridge, bridge_channel);
2218 
2219  ast_bridge_channel_clear_roles(bridge_channel);
2220 
2221  /* If we are not going to be hung up after leaving a bridge, and we were an
2222  * outgoing channel, clear the outgoing flag.
2223  */
2224  if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING)
2225  && (ast_channel_is_leaving_bridge(bridge_channel->chan)
2226  || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) {
2227  ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan));
2228  ast_channel_clear_flag(bridge_channel->chan, AST_FLAG_OUTGOING);
2229  }
2230 
2231  bridge->reconfigured = 1;
2232  ast_bridge_publish_leave(bridge, bridge_channel->chan);
2233 }
void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan)
Publish a bridge channel leave event.
void ast_bridge_channel_clear_roles(struct ast_bridge_channel *bridge_channel)
Clear all roles from a bridge_channel&#39;s role list.
Definition: bridge_roles.c:495
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
unsigned int num_active
Definition: bridge.h:383
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * name
Definition: bridge.h:267
unsigned int reconfigured
Definition: bridge.h:396
enum bridge_channel_state state
unsigned int suspended
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Definition: channel.c:11235
static void bridge_channel_dissolve_check(struct ast_bridge_channel *bridge_channel)
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_technology * technology
Definition: bridge.h:363
struct ast_flags feature_flags
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void(* leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Remove a channel from a bridging technology instance for a bridge.
unsigned int just_joined
int ast_channel_is_leaving_bridge(struct ast_channel *chan)
Determine if a channel is leaving a bridge, but not hung up.
Definition: channel.c:10751
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
Structure that contains information about a bridge.
Definition: bridge.h:357
unsigned int num_lonely
Definition: bridge.h:385
unsigned int in_bridge
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
Definition: search.h:40
ast_bridge_pull_channel_fn pull
Definition: bridge.h:275
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
unsigned int num_channels
Definition: bridge.h:381

◆ bridge_channel_internal_push()

int bridge_channel_internal_push ( struct ast_bridge_channel bridge_channel)

Definition at line 2315 of file bridge_channel.c.

References bridge_channel_internal_push_full().

Referenced by bridge_channel_internal_join(), bridge_do_merge(), and bridge_do_move().

2316 {
2317  return bridge_channel_internal_push_full(bridge_channel, 0);
2318 }
int bridge_channel_internal_push_full(struct ast_bridge_channel *bridge_channel, int optimized)

◆ bridge_channel_internal_push_full()

int bridge_channel_internal_push_full ( struct ast_bridge_channel bridge_channel,
int  optimized 
)

Definition at line 2235 of file bridge_channel.c.

References ast_assert, ast_bridge_channel_establish_roles(), AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_bridge_channel_leave_bridge(), AST_BRIDGE_FLAG_DISSOLVE_EMPTY, ast_bridge_publish_enter(), ast_channel_name(), ast_clear_flag, ast_debug, AST_LIST_INSERT_TAIL, ast_null_frame, ast_queue_frame(), ast_set2_flag, ast_test_flag, ast_verb, ast_bridge_channel::bridge, bridge_channel_cancel_owed_events(), bridge_channel_internal_pull(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_find_channel(), ast_bridge_channel::chan, ast_bridge::channels, ast_bridge::dissolved, ast_bridge_features::feature_flags, ast_bridge::feature_flags, ast_bridge_channel::features, ast_bridge_channel::in_bridge, ast_bridge_channel::just_joined, ast_bridge_technology::name, ast_bridge_methods::name, NULL, ast_bridge::num_active, ast_bridge::num_channels, ast_bridge::num_lonely, pbx_builtin_setvar_helper(), ast_bridge_methods::push, ast_bridge::reconfigured, ast_bridge_channel::state, ast_bridge_channel::suspended, ast_bridge_channel::swap, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by bridge_channel_internal_push(), and bridge_do_move().

2236 {
2237  struct ast_bridge *bridge = bridge_channel->bridge;
2238  struct ast_bridge_channel *swap;
2239 
2240  ast_assert(!bridge_channel->in_bridge);
2241 
2242  swap = bridge_find_channel(bridge, bridge_channel->swap);
2243  bridge_channel->swap = NULL;
2244 
2245  if (swap) {
2246  ast_debug(1, "Bridge %s: pushing %p(%s) by swapping with %p(%s)\n",
2247  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
2248  swap, ast_channel_name(swap->chan));
2249  } else {
2250  ast_debug(1, "Bridge %s: pushing %p(%s)\n",
2251  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2252  }
2253 
2254  /* Add channel to the bridge */
2255  if (bridge->dissolved
2256  || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2257  || (swap && swap->state != BRIDGE_CHANNEL_STATE_WAIT)
2258  || bridge->v_table->push(bridge, bridge_channel, swap)) {
2259  ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n",
2260  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2261  return -1;
2262  }
2263 
2264  ast_bridge_channel_establish_roles(bridge_channel);
2265 
2266  if (swap) {
2268 
2269  /* This flag is cleared so the act of this channel leaving does not cause it to dissolve if need be */
2271 
2272  if (optimized) {
2274  }
2277 
2279  }
2280 
2281  bridge_channel->in_bridge = 1;
2282  bridge_channel->just_joined = 1;
2283  AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
2284  ++bridge->num_channels;
2286  ++bridge->num_lonely;
2287  }
2288  if (!bridge_channel->suspended) {
2289  ++bridge->num_active;
2290  }
2291 
2292  ast_verb(3, "Channel %s %s%s%s '%s' %s-bridge <%s>\n",
2293  ast_channel_name(bridge_channel->chan),
2294  swap ? "swapped with " : "joined",
2295  swap ? ast_channel_name(swap->chan) : "",
2296  swap ? " into" : "",
2297  bridge->technology->name,
2298  bridge->v_table->name,
2299  bridge->uniqueid);
2300 
2301  ast_bridge_publish_enter(bridge, bridge_channel->chan, swap ? swap->chan : NULL);
2302 
2303  /* Clear any BLINDTRANSFER,ATTENDEDTRANSFER and FORWARDERNAME since the transfer has completed. */
2304  pbx_builtin_setvar_helper(bridge_channel->chan, "BLINDTRANSFER", NULL);
2305  pbx_builtin_setvar_helper(bridge_channel->chan, "ATTENDEDTRANSFER", NULL);
2306  pbx_builtin_setvar_helper(bridge_channel->chan, "FORWARDERNAME", NULL);
2307 
2308  /* Wake up the bridge channel thread to reevaluate any interval timers. */
2309  ast_queue_frame(bridge_channel->chan, &ast_null_frame);
2310 
2311  bridge->reconfigured = 1;
2312  return 0;
2313 }
struct ast_flags feature_flags
Definition: bridge.h:377
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
unsigned int num_active
Definition: bridge.h:383
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * name
Definition: bridge.h:267
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
unsigned int dissolved
Definition: bridge.h:398
unsigned int reconfigured
Definition: bridge.h:396
enum bridge_channel_state state
unsigned int suspended
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
#define NULL
Definition: resample.c:96
int ast_bridge_channel_establish_roles(struct ast_bridge_channel *bridge_channel)
Clone the roles from a bridge_channel&#39;s attached ast_channel onto the bridge_channel&#39;s role list...
Definition: bridge_roles.c:447
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_technology * technology
Definition: bridge.h:363
struct ast_flags feature_flags
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
unsigned int just_joined
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
Structure that contains information about a bridge.
Definition: bridge.h:357
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
unsigned int num_lonely
Definition: bridge.h:385
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
Publish a bridge channel enter event.
unsigned int in_bridge
struct ast_channel * swap
static void bridge_channel_cancel_owed_events(struct ast_bridge_channel *bridge_channel)
#define ast_clear_flag(p, flag)
Definition: utils.h:77
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_frame ast_null_frame
Definition: main/frame.c:79
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
Definition: search.h:40
ast_bridge_push_channel_fn push
Definition: bridge.h:273
unsigned int num_channels
Definition: bridge.h:381

◆ bridge_channel_internal_queue_attended_transfer()

int bridge_channel_internal_queue_attended_transfer ( struct ast_channel transferee,
struct ast_channel unbridged_chan 
)

Definition at line 3088 of file bridge_channel.c.

References ao2_cleanup, ast_channel_get_bridge_channel(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_name(), ast_channel_unlock, ast_copy_string(), BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, bridge_channel_queue_action_data(), NULL, and RAII_VAR.

Referenced by ast_bridge_transfer_attended().

3090 {
3091  RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
3092  char unbridged_chan_name[AST_CHANNEL_NAME];
3093 
3094  ast_channel_lock(transferee);
3095  transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
3096  ast_channel_unlock(transferee);
3097 
3098  if (!transferee_bridge_channel) {
3099  return -1;
3100  }
3101 
3102  ast_copy_string(unbridged_chan_name, ast_channel_name(unbridged_chan),
3103  sizeof(unbridged_chan_name));
3104 
3105  return bridge_channel_queue_action_data(transferee_bridge_channel,
3106  BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, unbridged_chan_name,
3107  sizeof(unbridged_chan_name));
3108 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static int bridge_channel_queue_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define AST_CHANNEL_NAME
Definition: channel.h:172
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)

◆ bridge_channel_internal_queue_blind_transfer()

int bridge_channel_internal_queue_blind_transfer ( struct ast_channel transferee,
const char *  exten,
const char *  context,
transfer_channel_cb  new_channel_cb,
void *  user_data 
)

Definition at line 3062 of file bridge_channel.c.

References ao2_cleanup, AST_BRIDGE_TRANSFER_SINGLE_PARTY, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, bridge_channel_queue_action_data(), blind_transfer_data::context, blind_transfer_data::exten, NULL, and RAII_VAR.

Referenced by ast_bridge_transfer_blind().

3065 {
3066  RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
3067  struct blind_transfer_data blind_data;
3068 
3069  ast_channel_lock(transferee);
3070  transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
3071  ast_channel_unlock(transferee);
3072 
3073  if (!transferee_bridge_channel) {
3074  return -1;
3075  }
3076 
3077  if (new_channel_cb) {
3078  new_channel_cb(transferee, user_data, AST_BRIDGE_TRANSFER_SINGLE_PARTY);
3079  }
3080 
3081  ast_copy_string(blind_data.exten, exten, sizeof(blind_data.exten));
3082  ast_copy_string(blind_data.context, context, sizeof(blind_data.context));
3083 
3084  return bridge_channel_queue_action_data(transferee_bridge_channel,
3085  BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, &blind_data, sizeof(blind_data));
3086 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
static int bridge_channel_queue_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
#define NULL
Definition: resample.c:96
Data specifying where a blind transfer is going to.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ bridge_channel_internal_suspend_nolock()

void bridge_channel_internal_suspend_nolock ( struct ast_bridge_channel bridge_channel)

Definition at line 854 of file bridge_channel.c.

References ast_bridge_channel::bridge, ast_bridge_channel::in_bridge, ast_bridge::num_active, ast_bridge_technology::suspend, ast_bridge_channel::suspended, and ast_bridge::technology.

Referenced by ast_bridge_channel_feature_digit(), ast_bridge_suspend(), and bridge_channel_suspend().

855 {
856  bridge_channel->suspended = 1;
857  if (bridge_channel->in_bridge) {
858  --bridge_channel->bridge->num_active;
859  }
860 
861  /* Get technology bridge threads off of the channel. */
862  if (bridge_channel->bridge->technology->suspend) {
863  bridge_channel->bridge->technology->suspend(bridge_channel->bridge, bridge_channel);
864  }
865 }
unsigned int num_active
Definition: bridge.h:383
void(* suspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Suspend a channel on a bridging technology instance for a bridge.
unsigned int suspended
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_technology * technology
Definition: bridge.h:363
unsigned int in_bridge

◆ bridge_channel_internal_unsuspend_nolock()

void bridge_channel_internal_unsuspend_nolock ( struct ast_bridge_channel bridge_channel)

Definition at line 892 of file bridge_channel.c.

References ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_cond_signal, ast_bridge_channel::bridge, ast_bridge_channel::cond, ast_bridge_channel::in_bridge, ast_bridge::num_active, ast_bridge_channel::suspended, ast_bridge::technology, and ast_bridge_technology::unsuspend.

Referenced by ast_bridge_unsuspend(), and bridge_channel_unsuspend().

893 {
894  bridge_channel->suspended = 0;
895  if (bridge_channel->in_bridge) {
896  ++bridge_channel->bridge->num_active;
897  }
898 
899  /* Wake technology bridge threads to take care of channel again. */
900  if (bridge_channel->bridge->technology->unsuspend) {
901  bridge_channel->bridge->technology->unsuspend(bridge_channel->bridge, bridge_channel);
902  }
903 
904  /* Wake suspended channel. */
905  ast_bridge_channel_lock(bridge_channel);
906  ast_cond_signal(&bridge_channel->cond);
907  ast_bridge_channel_unlock(bridge_channel);
908 }
unsigned int num_active
Definition: bridge.h:383
unsigned int suspended
#define ast_cond_signal(cond)
Definition: lock.h:201
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
unsigned int in_bridge
void(* unsuspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Unsuspend a channel on a bridging technology instance for a bridge.

◆ bridge_channel_next_interval()

static int bridge_channel_next_interval ( struct ast_bridge_channel bridge_channel)
static

Definition at line 2720 of file bridge_channel.c.

References ast_heap_peek(), ast_heap_unlock, ast_heap_wrlock, ast_tvdiff_ms(), ast_tvnow(), ast_bridge_channel::features, ast_bridge_features::interval_hooks, ast_bridge_hook_timer::timer, and ast_bridge_hook_timer_parms::trip_time.

Referenced by bridge_channel_next_timeout().

2721 {
2722  struct ast_heap *interval_hooks = bridge_channel->features->interval_hooks;
2723  struct ast_bridge_hook_timer *hook;
2724  int ms;
2725 
2726  ast_heap_wrlock(interval_hooks);
2727  hook = ast_heap_peek(interval_hooks, 1);
2728  if (hook) {
2729  ms = ast_tvdiff_ms(hook->timer.trip_time, ast_tvnow());
2730  if (ms < 0) {
2731  /* Expire immediately. An interval hook is ready to run. */
2732  ms = 0;
2733  }
2734  } else {
2735  /* No hook so wait forever. */
2736  ms = -1;
2737  }
2738  ast_heap_unlock(interval_hooks);
2739 
2740  return ms;
2741 }
struct ast_bridge_features * features
#define ast_heap_unlock(h)
Definition: heap.h:248
Definition: heap.c:36
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
struct ast_heap * interval_hooks
struct ast_bridge_hook_timer_parms timer
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
#define ast_heap_wrlock(h)
Definition: heap.h:246

◆ bridge_channel_next_timeout()

static int bridge_channel_next_timeout ( struct ast_bridge_channel bridge_channel)
static

Definition at line 2782 of file bridge_channel.c.

References bridge_channel_feature_timeout(), and bridge_channel_next_interval().

Referenced by bridge_channel_wait().

2783 {
2784  int ms_interval;
2785  int ms;
2786 
2787  ms_interval = bridge_channel_next_interval(bridge_channel);
2788  ms = bridge_channel_feature_timeout(bridge_channel);
2789  if (ms < 0 || (0 <= ms_interval && ms_interval < ms)) {
2790  /* Interval hook timeout is next. */
2791  ms = ms_interval;
2792  }
2793 
2794  return ms;
2795 }
static int bridge_channel_next_interval(struct ast_bridge_channel *bridge_channel)
static int bridge_channel_feature_timeout(struct ast_bridge_channel *bridge_channel)

◆ bridge_channel_park()

static void bridge_channel_park ( struct ast_bridge_channel bridge_channel,
struct bridge_park payload 
)
static

Definition at line 1511 of file bridge_channel.c.

References bridge_park::app_data_offset, ast_channel_name(), ast_log, AST_LOG_WARNING, ast_parking_park_bridge_channel(), ast_parking_provider_registered(), ast_bridge_channel::chan, NULL, bridge_park::parkee_uuid, and bridge_park::parker_uuid_offset.

Referenced by bridge_channel_handle_action().

1512 {
1514  ast_log(AST_LOG_WARNING, "Unable to park %s: No parking provider loaded!\n",
1515  ast_channel_name(bridge_channel->chan));
1516  return;
1517  }
1518 
1519  if (ast_parking_park_bridge_channel(bridge_channel, payload->parkee_uuid,
1520  &payload->parkee_uuid[payload->parker_uuid_offset],
1521  payload->app_data_offset ? &payload->parkee_uuid[payload->app_data_offset] : NULL)) {
1522  ast_log(AST_LOG_WARNING, "Error occurred while parking %s\n",
1523  ast_channel_name(bridge_channel->chan));
1524  }
1525 }
#define AST_LOG_WARNING
Definition: logger.h:279
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
char parkee_uuid[0]
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
Definition: parking.c:241
int ast_parking_park_bridge_channel(struct ast_bridge_channel *parkee, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
Perform a direct park on a channel in a bridge.
Definition: parking.c:126
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)

◆ bridge_channel_playfile()

static void bridge_channel_playfile ( struct ast_bridge_channel bridge_channel,
struct bridge_playfile payload 
)
static

Definition at line 1368 of file bridge_channel.c.

References ast_bridge_channel_playfile(), bridge_playfile::custom_play, bridge_playfile::moh_offset, NULL, and bridge_playfile::playfile.

Referenced by bridge_channel_handle_action().

1369 {
1370  ast_bridge_channel_playfile(bridge_channel, payload->custom_play, payload->playfile,
1371  payload->moh_offset ? &payload->playfile[payload->moh_offset] : NULL);
1372 }
ast_bridge_custom_play_fn custom_play
#define NULL
Definition: resample.c:96
void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Play a file on the bridge channel.

◆ bridge_channel_poke()

static void bridge_channel_poke ( struct ast_bridge_channel bridge_channel)
static

Definition at line 259 of file bridge_channel.c.

References ast_null_frame, ast_queue_frame(), ast_bridge_channel::chan, and ast_bridge_channel::thread.

Referenced by ast_bridge_channel_leave_bridge_nolock().

260 {
261  if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
262  /* Wake up the bridge channel thread. */
263  ast_queue_frame(bridge_channel->chan, &ast_null_frame);
264  }
265 }
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
struct ast_frame ast_null_frame
Definition: main/frame.c:79
struct ast_channel * chan

◆ bridge_channel_queue_action_data()

static int bridge_channel_queue_action_data ( struct ast_bridge_channel bridge_channel,
enum bridge_channel_action_type  action,
const void *  data,
size_t  datalen 
)
static

Definition at line 938 of file bridge_channel.c.

References ast_bridge_channel_queue_frame(), AST_FRAME_BRIDGE_ACTION, ast_frame::datalen, and ast_frame::frametype.

Referenced by ast_bridge_channel_queue_app(), ast_bridge_channel_queue_callback(), ast_bridge_channel_queue_playfile(), bridge_channel_internal_queue_attended_transfer(), and bridge_channel_internal_queue_blind_transfer().

940 {
941  struct ast_frame frame = {
943  .subclass.integer = action,
944  .datalen = datalen,
945  .data.ptr = (void *) data,
946  };
947 
948  return ast_bridge_channel_queue_frame(bridge_channel, &frame);
949 }
int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
Write a frame to the specified bridge_channel.
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype

◆ bridge_channel_queue_action_data_sync()

static int bridge_channel_queue_action_data_sync ( struct ast_bridge_channel bridge_channel,
enum bridge_channel_action_type  action,
const void *  data,
size_t  datalen 
)
static

Definition at line 966 of file bridge_channel.c.

References ast_alloca, ast_assert, ast_atomic_fetchadd_int(), ast_bridge_channel_queue_frame(), AST_FRAME_BRIDGE_ACTION_SYNC, bridge_sync_cleanup(), bridge_sync_init(), bridge_sync_wait(), sync_payload::data, ast_frame::data, ast_frame::datalen, ast_frame::frametype, sync_payload::id, ast_frame::ptr, sync_ids, and ast_bridge_channel::thread.

Referenced by ast_bridge_channel_queue_playfile_sync().

968 {
969  struct sync_payload *sync_payload;
970  int sync_payload_len = sizeof(*sync_payload) + datalen;
971  struct bridge_sync sync_struct;
972  struct ast_frame frame = {
974  .subclass.integer = action,
975  };
976 
977  /* Make sure we don't end up trying to wait on ourself to deliver the frame */
978  ast_assert(!pthread_equal(pthread_self(), bridge_channel->thread));
979 
980  sync_payload = ast_alloca(sync_payload_len);
981  sync_payload->id = ast_atomic_fetchadd_int(&sync_ids, +1);
982  memcpy(sync_payload->data, data, datalen);
983 
984  frame.datalen = sync_payload_len;
985  frame.data.ptr = sync_payload;
986 
987  bridge_sync_init(&sync_struct, sync_payload->id);
988  if (ast_bridge_channel_queue_frame(bridge_channel, &frame)) {
989  bridge_sync_cleanup(&sync_struct);
990  return -1;
991  }
992 
993  bridge_sync_wait(&sync_struct);
994  bridge_sync_cleanup(&sync_struct);
995  return 0;
996 }
unsigned int id
static void bridge_sync_wait(struct bridge_sync *sync_struct)
Wait for a synchronous bridge action to complete.
static void bridge_sync_init(struct bridge_sync *sync_struct, unsigned int id)
initialize a synchronous bridge object.
int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
Write a frame to the specified bridge_channel.
#define ast_assert(a)
Definition: utils.h:695
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
Frame payload for synchronous bridge actions.
static int sync_ids
Counter used for assigning synchronous bridge action IDs.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
Data structure associated with a single frame of data.
static void bridge_sync_cleanup(struct bridge_sync *sync_struct)
Clean up a syncrhonization bridge object.
Synchronous bridge action object.
union ast_frame::@263 data
enum ast_frame_type frametype
unsigned char data[0]

◆ bridge_channel_queue_deferred_frames()

void bridge_channel_queue_deferred_frames ( struct ast_bridge_channel bridge_channel)

Definition at line 830 of file bridge_channel.c.

References ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_channel_lock, ast_channel_unlock, ast_frfree, AST_LIST_REMOVE_HEAD, ast_queue_frame_head(), ast_bridge_channel::chan, and ast_bridge_channel::deferred_queue.

Referenced by bridge_complete_join().

831 {
832  struct ast_frame *frame;
833 
834  ast_bridge_channel_lock(bridge_channel);
835  ast_channel_lock(bridge_channel->chan);
836  while ((frame = AST_LIST_REMOVE_HEAD(&bridge_channel->deferred_queue, frame_list))) {
837  ast_queue_frame_head(bridge_channel->chan, frame);
838  ast_frfree(frame);
839  }
840  ast_channel_unlock(bridge_channel->chan);
841  ast_bridge_channel_unlock(bridge_channel);
842 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge_channel::@231 deferred_queue
struct ast_channel * chan
#define ast_frfree(fr)
Data structure associated with a single frame of data.
int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to the head of a channel&#39;s frame queue.
Definition: channel.c:1144

◆ bridge_channel_run_app()

static void bridge_channel_run_app ( struct ast_bridge_channel bridge_channel,
struct bridge_run_app data 
)
static

Definition at line 1274 of file bridge_channel.c.

References bridge_run_app::app_args_offset, bridge_run_app::app_name, ast_bridge_channel_run_app(), bridge_run_app::moh_offset, and NULL.

Referenced by bridge_channel_handle_action().

1275 {
1276  ast_bridge_channel_run_app(bridge_channel, data->app_name,
1277  data->app_args_offset ? &data->app_name[data->app_args_offset] : NULL,
1278  data->moh_offset ? &data->app_name[data->moh_offset] : NULL);
1279 }
#define NULL
Definition: resample.c:96
void ast_bridge_channel_run_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
Run an application on the bridge channel.

◆ bridge_channel_settle_owed_events()

void bridge_channel_settle_owed_events ( struct ast_bridge orig_bridge,
struct ast_bridge_channel bridge_channel 
)

Definition at line 792 of file bridge_channel.c.

References ast_channel_name(), AST_CONTROL_T38_PARAMETERS, ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, ast_log, AST_T38_TERMINATED, ast_tvdiff_ms(), ast_tvnow(), ast_bridge_channel::chan, ast_bridge_channel::dtmf_digit, ast_bridge_channel::dtmf_tv, ast_frame::frametype, ast_frame::len, LOG_DTMF, NULL, option_dtmfminduration, ast_bridge_channel::owed, ast_control_t38_parameters::request_response, ast_frame::src, ast_bridge_channel::t38_terminate, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge_technology::write.

Referenced by bridge_channel_internal_join(), and bridge_do_move().

793 {
794  if (bridge_channel->owed.dtmf_digit) {
795  struct ast_frame frame = {
797  .subclass.integer = bridge_channel->owed.dtmf_digit,
798  .src = "Bridge channel owed DTMF",
799  };
800 
801  frame.len = ast_tvdiff_ms(ast_tvnow(), bridge_channel->owed.dtmf_tv);
802  if (frame.len < option_dtmfminduration) {
803  frame.len = option_dtmfminduration;
804  }
805  ast_log(LOG_DTMF, "DTMF end '%c' simulated to bridge %s because %s left. Duration %ld ms.\n",
806  bridge_channel->owed.dtmf_digit, orig_bridge->uniqueid,
807  ast_channel_name(bridge_channel->chan), frame.len);
808  bridge_channel->owed.dtmf_digit = '\0';
809  orig_bridge->technology->write(orig_bridge, NULL, &frame);
810  }
811  if (bridge_channel->owed.t38_terminate) {
812  struct ast_control_t38_parameters t38_parameters = {
814  };
815  struct ast_frame frame = {
817  .subclass.integer = AST_CONTROL_T38_PARAMETERS,
818  .data.ptr = &t38_parameters,
819  .datalen = sizeof(t38_parameters),
820  .src = "Bridge channel owed T.38 terminate",
821  };
822 
823  ast_debug(1, "T.38 terminate simulated to bridge %s because %s left.\n",
824  orig_bridge->uniqueid, ast_channel_name(bridge_channel->chan));
825  bridge_channel->owed.t38_terminate = 0;
826  orig_bridge->technology->write(orig_bridge, NULL, &frame);
827  }
828 }
const ast_string_field uniqueid
Definition: bridge.h:409
unsigned int option_dtmfminduration
Definition: options.c:83
enum ast_control_t38 request_response
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
struct timeval dtmf_tv
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const char * src
int(* write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Write a frame into the bridging technology instance for a bridge.
struct ast_bridge_channel::@232 owed
#define LOG_DTMF
Definition: logger.h:307
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
Data structure associated with a single frame of data.
enum ast_frame_type frametype

◆ bridge_channel_suspend()

static void bridge_channel_suspend ( struct ast_bridge_channel bridge_channel)
static

Definition at line 875 of file bridge_channel.c.

References ast_bridge_channel_lock_bridge(), ast_bridge_unlock, ast_bridge_channel::bridge, and bridge_channel_internal_suspend_nolock().

Referenced by bridge_channel_do_callback(), bridge_channel_event_join_leave(), bridge_channel_handle_action(), and bridge_channel_handle_interval().

876 {
877  ast_bridge_channel_lock_bridge(bridge_channel);
879  ast_bridge_unlock(bridge_channel->bridge);
880 }
void bridge_channel_internal_suspend_nolock(struct ast_bridge_channel *bridge_channel)
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.

◆ bridge_channel_talking()

static void bridge_channel_talking ( struct ast_bridge_channel bridge_channel,
int  talking 
)
static

Definition at line 1899 of file bridge_channel.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ao2_unlink, AST_BRIDGE_HOOK_TYPE_TALK, ast_channel_name(), ast_debug, ast_bridge_hook::callback, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_hook::hook_pvt, ast_bridge_features::other_hooks, and ast_bridge_hook::type.

Referenced by bridge_channel_handle_action().

1900 {
1901  struct ast_bridge_features *features = bridge_channel->features;
1902  struct ast_bridge_hook *hook;
1903  struct ao2_iterator iter;
1904 
1905  /* Run any talk detection hooks. */
1906  iter = ao2_iterator_init(features->other_hooks, 0);
1907  for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
1908  int remove_me;
1910 
1911  if (hook->type != AST_BRIDGE_HOOK_TYPE_TALK) {
1912  continue;
1913  }
1915  remove_me = talk_cb(bridge_channel, hook->hook_pvt, talking);
1916  if (remove_me) {
1917  ast_debug(1, "Talk detection hook %p is being removed from %p(%s)\n",
1918  hook, bridge_channel, ast_channel_name(bridge_channel->chan));
1919  ao2_unlink(features->other_hooks, hook);
1920  }
1921  }
1922  ao2_iterator_destroy(&iter);
1923 }
struct ast_bridge_features * features
int(* ast_bridge_talking_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
Talking indicator callback.
Structure that contains features information.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
enum ast_bridge_hook_type type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
ast_bridge_hook_callback callback
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ast_channel * chan
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_container * other_hooks
const char * ast_channel_name(const struct ast_channel *chan)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
Structure that is the essence of a feature hook.

◆ bridge_channel_unsuspend()

static void bridge_channel_unsuspend ( struct ast_bridge_channel bridge_channel)
static

Definition at line 918 of file bridge_channel.c.

References ast_bridge_channel_lock_bridge(), ast_bridge_unlock, ast_bridge_channel::bridge, and bridge_channel_internal_unsuspend_nolock().

Referenced by ast_bridge_channel_feature_digit(), bridge_channel_do_callback(), bridge_channel_event_join_leave(), bridge_channel_handle_action(), and bridge_channel_handle_interval().

919 {
920  ast_bridge_channel_lock_bridge(bridge_channel);
922  ast_bridge_unlock(bridge_channel->bridge);
923 }
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void bridge_channel_internal_unsuspend_nolock(struct ast_bridge_channel *bridge_channel)
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.

◆ bridge_channel_update_accountcodes_joining()

static void bridge_channel_update_accountcodes_joining ( struct ast_bridge_channel joining,
struct ast_bridge_channel swap 
)
static

Definition at line 529 of file bridge_channel.c.

References ast_assert, ast_channel_lock_both, ast_channel_unlock, AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge_channel::chan, channel_set_empty_accountcodes(), channel_update_peeraccounts(), ast_bridge::channels, and ast_bridge::num_channels.

Referenced by ast_bridge_channel_update_accountcodes().

530 {
531  struct ast_bridge *bridge = joining->bridge;
532  struct ast_bridge_channel *other;
533  unsigned int swap_in_bridge = 0;
534  unsigned int will_be_two_party;
535 
536  /*
537  * Only update the peeraccount to match if the joining channel
538  * will make it a two party bridge.
539  */
540  if (bridge->num_channels <= 2 && swap) {
541  AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
542  if (other == swap) {
543  swap_in_bridge = 1;
544  break;
545  }
546  }
547  }
548  will_be_two_party = (1 == bridge->num_channels - swap_in_bridge);
549 
550  AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
551  if (other == swap) {
552  continue;
553  }
554  ast_assert(joining != other);
555  ast_channel_lock_both(joining->chan, other->chan);
556  channel_set_empty_accountcodes(joining->chan, other->chan);
557  if (will_be_two_party) {
558  channel_update_peeraccounts(joining->chan, other->chan);
559  }
560  ast_channel_unlock(joining->chan);
561  ast_channel_unlock(other->chan);
562  }
563 }
static void channel_set_empty_accountcodes(struct ast_channel *c0, struct ast_channel *c1)
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge * bridge
Bridge this channel is participating in.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
static void channel_update_peeraccounts(struct ast_channel *c0, struct ast_channel *c1)
unsigned int num_channels
Definition: bridge.h:381

◆ bridge_channel_update_accountcodes_leaving()

static void bridge_channel_update_accountcodes_leaving ( struct ast_bridge_channel leaving)
static

Definition at line 576 of file bridge_channel.c.

References ast_assert, ast_channel_lock_both, ast_channel_unlock, AST_LIST_FIRST, AST_LIST_LAST, ast_bridge_channel::bridge, ast_bridge_channel::chan, channel_set_empty_accountcodes(), channel_update_peeraccounts(), ast_bridge::channels, ast_bridge::dissolved, first, and ast_bridge::num_channels.

Referenced by ast_bridge_channel_update_accountcodes().

577 {
578  struct ast_bridge *bridge = leaving->bridge;
579  struct ast_bridge_channel *first;
580  struct ast_bridge_channel *second;
581 
582  if (bridge->num_channels != 2 || bridge->dissolved) {
583  return;
584  }
585 
586  first = AST_LIST_FIRST(&bridge->channels);
587  second = AST_LIST_LAST(&bridge->channels);
588  ast_assert(first && first != second);
589  ast_channel_lock_both(first->chan, second->chan);
590  channel_set_empty_accountcodes(first->chan, second->chan);
591  channel_update_peeraccounts(first->chan, second->chan);
592  ast_channel_unlock(second->chan);
593  ast_channel_unlock(first->chan);
594 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
static void channel_set_empty_accountcodes(struct ast_channel *c0, struct ast_channel *c1)
unsigned int dissolved
Definition: bridge.h:398
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge * bridge
Bridge this channel is participating in.
Structure that contains information about a bridge.
Definition: bridge.h:357
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
static void channel_update_peeraccounts(struct ast_channel *c0, struct ast_channel *c1)
unsigned int num_channels
Definition: bridge.h:381

◆ bridge_channel_wait()

static void bridge_channel_wait ( struct ast_bridge_channel bridge_channel)
static

Definition at line 2808 of file bridge_channel.c.

References ast_bridge_channel::activity, ast_bridge_channel::alert_pipe, ao2_object_get_lockaddr(), ast_bridge_channel_lock, ast_bridge_channel_lock_bridge(), ast_bridge_channel_unlock, ast_bridge_unlock, ast_channel_name(), ast_channel_set_unbridged(), ast_channel_unbridged(), ast_cond_wait, ast_debug, ast_waitfor_nandfds(), ast_bridge_channel::bridge, bridge_channel_handle_feature_timeout(), bridge_channel_handle_interval(), bridge_channel_handle_write(), bridge_channel_next_timeout(), BRIDGE_CHANNEL_STATE_WAIT, BRIDGE_CHANNEL_THREAD_FRAME, BRIDGE_CHANNEL_THREAD_IDLE, bridge_handle_trip(), bridge_reconfigured(), ast_bridge_channel::chan, ast_bridge_channel::cond, NULL, ast_bridge::reconfigured, ast_bridge_channel::state, ast_bridge_channel::suspended, and ast_bridge::uniqueid.

Referenced by bridge_channel_internal_join().

2809 {
2810  int ms;
2811  int outfd;
2812  struct ast_channel *chan;
2813 
2814  /* Wait for data to either come from the channel or us to be signaled */
2815  ast_bridge_channel_lock(bridge_channel);
2816  if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2817  } else if (bridge_channel->suspended) {
2818 /* XXX ASTERISK-21271 the external party use of suspended will go away as will these references because this is the bridge channel thread */
2819  ast_debug(1, "Bridge %s: %p(%s) is going into a signal wait\n",
2820  bridge_channel->bridge->uniqueid, bridge_channel,
2821  ast_channel_name(bridge_channel->chan));
2822  ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
2823  } else {
2824  ast_bridge_channel_unlock(bridge_channel);
2825  outfd = -1;
2826  ms = bridge_channel_next_timeout(bridge_channel);
2827  chan = ast_waitfor_nandfds(&bridge_channel->chan, 1,
2828  &bridge_channel->alert_pipe[0], 1, NULL, &outfd, &ms);
2829  if (ast_channel_unbridged(bridge_channel->chan)) {
2830  ast_channel_set_unbridged(bridge_channel->chan, 0);
2831  ast_bridge_channel_lock_bridge(bridge_channel);
2832  bridge_channel->bridge->reconfigured = 1;
2833  bridge_reconfigured(bridge_channel->bridge, 0);
2834  ast_bridge_unlock(bridge_channel->bridge);
2835  }
2836  ast_bridge_channel_lock(bridge_channel);
2837  bridge_channel->activity = BRIDGE_CHANNEL_THREAD_FRAME;
2838  ast_bridge_channel_unlock(bridge_channel);
2839  if (!bridge_channel->suspended
2840  && bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2841  if (chan) {
2842  bridge_handle_trip(bridge_channel);
2843  } else if (ms == 0) {
2844  /* An interdigit timeout or interval expired. */
2845  bridge_channel_handle_feature_timeout(bridge_channel);
2846  bridge_channel_handle_interval(bridge_channel);
2847  } else if (-1 < outfd) {
2848  /*
2849  * Must do this after checking timeouts or may have
2850  * an infinite loop due to deferring write queue
2851  * actions while trying to match DTMF feature hooks.
2852  */
2853  bridge_channel_handle_write(bridge_channel);
2854  }
2855  }
2856  bridge_channel->activity = BRIDGE_CHANNEL_THREAD_IDLE;
2857  return;
2858  }
2859  ast_bridge_channel_unlock(bridge_channel);
2860 }
Main Channel structure associated with a channel.
enum bridge_channel_thread_state activity
The bridge channel thread activity.
const ast_string_field uniqueid
Definition: bridge.h:409
unsigned int reconfigured
Definition: bridge.h:396
enum bridge_channel_state state
unsigned int suspended
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
static void bridge_handle_trip(struct ast_bridge_channel *bridge_channel)
#define NULL
Definition: resample.c:96
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition: channel.c:2997
struct ast_bridge * bridge
Bridge this channel is participating in.
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
static void bridge_channel_handle_interval(struct ast_bridge_channel *bridge_channel)
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1443
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
static void bridge_channel_handle_write(struct ast_bridge_channel *bridge_channel)
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
int ast_channel_unbridged(struct ast_channel *chan)
This function will check if the bridge needs to be re-evaluated due to external changes.
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
static void bridge_channel_handle_feature_timeout(struct ast_bridge_channel *bridge_channel)
void ast_channel_set_unbridged(struct ast_channel *chan, int value)
Sets the unbridged flag and queues a NULL frame on the channel to trigger a check by bridge_channel_w...
static int bridge_channel_next_timeout(struct ast_bridge_channel *bridge_channel)

◆ bridge_channel_write_action_data()

static int bridge_channel_write_action_data ( struct ast_bridge_channel bridge_channel,
enum bridge_channel_action_type  action,
const void *  data,
size_t  datalen 
)
static

Definition at line 1010 of file bridge_channel.c.

References AST_FRAME_BRIDGE_ACTION, bridge_channel_write_frame(), ast_frame::datalen, and ast_frame::frametype.

Referenced by ast_bridge_channel_write_app(), ast_bridge_channel_write_callback(), ast_bridge_channel_write_park(), ast_bridge_channel_write_playfile(), and bridge_channel_write_dtmf_stream().

1012 {
1013  struct ast_frame frame = {
1015  .subclass.integer = action,
1016  .datalen = datalen,
1017  .data.ptr = (void *) data,
1018  };
1019 
1020  return bridge_channel_write_frame(bridge_channel, &frame);
1021 }
static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype

◆ bridge_channel_write_dtmf_stream()

static int bridge_channel_write_dtmf_stream ( struct ast_bridge_channel bridge_channel,
const char *  dtmf 
)
static

Definition at line 1659 of file bridge_channel.c.

References BRIDGE_CHANNEL_ACTION_DTMF_STREAM, and bridge_channel_write_action_data().

Referenced by ast_bridge_channel_feature_digit().

1660 {
1661  return bridge_channel_write_action_data(bridge_channel,
1662  BRIDGE_CHANNEL_ACTION_DTMF_STREAM, dtmf, strlen(dtmf) + 1);
1663 }
static int bridge_channel_write_action_data(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)

◆ bridge_channel_write_frame()

static int bridge_channel_write_frame ( struct ast_bridge_channel bridge_channel,
struct ast_frame frame 
)
static

Definition at line 650 of file bridge_channel.c.

References ast_assert, ast_bridge_channel_lock, ast_bridge_channel_lock_bridge(), ast_bridge_channel_unlock, ast_bridge_unlock, ast_channel_is_multistream(), AST_CONTROL_T38_PARAMETERS, AST_FRAME_BRIDGE_ACTION_SYNC, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_IMAGE, AST_FRAME_RTCP, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup, AST_LIST_INSERT_HEAD, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_tvnow(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_bridge_channel::bridge, ast_bridge_channel::chan, ast_frame::data, ast_bridge_channel::deferred_queue, ast_bridge_channel::dtmf_digit, ast_bridge_channel::dtmf_tv, ast_frame::frametype, ast_frame_subclass::integer, ast_bridge_channel::owed, ast_frame::ptr, ast_control_t38_parameters::request_response, ast_bridge_channel::stream_map, ast_frame::stream_num, ast_frame::subclass, ast_bridge_channel::t38_terminate, ast_bridge::technology, ast_bridge_channel::to_bridge, and ast_bridge_technology::write.

Referenced by ast_bridge_channel_write_control_data(), bridge_channel_write_action_data(), and bridge_handle_trip().

651 {
652  const struct ast_control_t38_parameters *t38_parameters;
653  int unmapped_stream_num;
654  int deferred;
655 
657 
658  ast_bridge_channel_lock_bridge(bridge_channel);
659 
660  /*
661  * Map the frame to the bridge.
662  * We need to lock the bridge_channel to make sure that bridge_channel->chan
663  * isn't NULL and keep it locked while we do multistream processing.
664  */
665  ast_bridge_channel_lock(bridge_channel);
666  if (bridge_channel->chan && ast_channel_is_multistream(bridge_channel->chan)) {
667  unmapped_stream_num = frame->stream_num;
668  switch (frame->frametype) {
669  case AST_FRAME_VOICE:
670  case AST_FRAME_VIDEO:
671  case AST_FRAME_TEXT:
672  case AST_FRAME_IMAGE:
673  case AST_FRAME_RTCP:
674  /* These frames need to be mapped to an appropriate write stream */
675  if (frame->stream_num < 0) {
676  /* Map to default stream */
677  frame->stream_num = -1;
678  break;
679  }
680  if (frame->stream_num < (int)AST_VECTOR_SIZE(&bridge_channel->stream_map.to_bridge)) {
681  frame->stream_num = AST_VECTOR_GET(
682  &bridge_channel->stream_map.to_bridge, frame->stream_num);
683  if (0 <= frame->stream_num) {
684  break;
685  }
686  }
687  ast_bridge_channel_unlock(bridge_channel);
688  ast_bridge_unlock(bridge_channel->bridge);
689  /*
690  * Ignore frame because we don't know how to map the frame
691  * or the bridge is not expecting any media from that
692  * stream.
693  */
694  return 0;
696  case AST_FRAME_DTMF_END:
697  /*
698  * XXX It makes sense that DTMF could be on any audio stream.
699  * For now we will only put it on the default audio stream.
700  */
701  default:
702  frame->stream_num = -1;
703  break;
704  }
705  } else {
706  unmapped_stream_num = -1;
707  frame->stream_num = -1;
708  }
709  ast_bridge_channel_unlock(bridge_channel);
710 
711  deferred = bridge_channel->bridge->technology->write(bridge_channel->bridge, bridge_channel, frame);
712  if (deferred) {
713  struct ast_frame *dup;
714 
715  dup = ast_frdup(frame);
716  if (dup) {
717  /*
718  * We have to unmap the deferred frame so it comes back
719  * in like a new frame.
720  */
721  dup->stream_num = unmapped_stream_num;
722  ast_bridge_channel_lock(bridge_channel);
723  AST_LIST_INSERT_HEAD(&bridge_channel->deferred_queue, dup, frame_list);
724  ast_bridge_channel_unlock(bridge_channel);
725  }
726  }
727 
728  /* Remember any owed events to the bridge. */
729  switch (frame->frametype) {
731  bridge_channel->owed.dtmf_tv = ast_tvnow();
732  bridge_channel->owed.dtmf_digit = frame->subclass.integer;
733  break;
734  case AST_FRAME_DTMF_END:
735  bridge_channel->owed.dtmf_digit = '\0';
736  break;
737  case AST_FRAME_CONTROL:
738  /*
739  * We explicitly will not remember HOLD/UNHOLD frames because
740  * things like attended transfers will handle them.
741  */
742  switch (frame->subclass.integer) {
744  t38_parameters = frame->data.ptr;
745  switch (t38_parameters->request_response) {
747  case AST_T38_NEGOTIATED:
748  bridge_channel->owed.t38_terminate = 1;
749  break;
751  case AST_T38_TERMINATED:
752  case AST_T38_REFUSED:
753  bridge_channel->owed.t38_terminate = 0;
754  break;
755  default:
756  break;
757  }
758  break;
759  default:
760  break;
761  }
762  break;
763  default:
764  break;
765  }
766  ast_bridge_unlock(bridge_channel->bridge);
767 
768  /*
769  * Claim successful write to bridge. If deferred frame
770  * support is added, claim successfully deferred.
771  */
772  return 0;
773 }
#define ast_frdup(fr)
Copies a frame.
int ast_channel_is_multistream(struct ast_channel *chan)
Determine if a channel is multi-stream capable.
enum ast_control_t38 request_response
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge_channel::@236 stream_map
struct timeval dtmf_tv
struct ast_vector_int to_bridge
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_frame_subclass subclass
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
int(* write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Write a frame into the bridging technology instance for a bridge.
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
struct ast_bridge_channel::@232 owed
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ast_bridge_channel::@231 deferred_queue
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
struct ast_channel * chan
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ bridge_frame_free()

static void bridge_frame_free ( struct ast_frame frame)
static

Definition at line 1023 of file bridge_channel.c.

References AST_FRAME_BRIDGE_ACTION_SYNC, ast_frfree, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, bridge_sync_signal(), ast_frame::data, ast_frame::frametype, sync_payload::id, bridge_sync::id, bridge_sync::list, and ast_frame::ptr.

Referenced by ast_bridge_channel_queue_frame(), bridge_channel_destroy(), bridge_channel_handle_write(), bridge_handle_dtmf(), and bridge_handle_trip().

1024 {
1025  if (frame->frametype == AST_FRAME_BRIDGE_ACTION_SYNC) {
1026  struct sync_payload *sync_payload = frame->data.ptr;
1027  struct bridge_sync *sync;
1028 
1031  if (sync->id == sync_payload->id) {
1032  break;
1033  }
1034  }
1035  if (sync) {
1036  bridge_sync_signal(sync);
1037  }
1039  }
1040 
1041  ast_frfree(frame);
1042 }
unsigned int id
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Frame payload for synchronous bridge actions.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
List holding active synchronous action objects.
struct bridge_sync::@354 list
#define ast_frfree(fr)
Synchronous bridge action object.
union ast_frame::@263 data
enum ast_frame_type frametype
static void bridge_sync_signal(struct bridge_sync *sync_struct)
Signal that waiting for a synchronous bridge action is no longer necessary.
unsigned int id

◆ bridge_handle_dtmf()

static struct ast_frame* bridge_handle_dtmf ( struct ast_bridge_channel bridge_channel,
struct ast_frame frame 
)
static

Internal function to handle DTMF from a channel.

Definition at line 2548 of file bridge_channel.c.

References ao2_cleanup, ao2_find, ast_assert, ast_bridge_channel_feature_digit(), AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_test_suite_event_notify, bridge_frame_free(), ast_bridge_channel::collected, ast_bridge_hook_dtmf::dtmf, ast_bridge_channel::dtmf_hook_state, ast_bridge_features::dtmf_hooks, ast_bridge_channel::features, ast_frame::frametype, ast_frame_subclass::integer, NULL, OBJ_SEARCH_PARTIAL_KEY, and ast_frame::subclass.

Referenced by bridge_handle_trip().

2549 {
2550  struct ast_bridge_features *features = bridge_channel->features;
2551  struct ast_bridge_hook_dtmf *hook = NULL;
2552  char dtmf[2];
2553 
2554  /*
2555  * See if we are already matching a DTMF feature hook sequence or
2556  * if this DTMF matches the beginning of any DTMF feature hooks.
2557  */
2558  dtmf[0] = frame->subclass.integer;
2559  dtmf[1] = '\0';
2560  if (bridge_channel->dtmf_hook_state.collected[0]
2561  || (hook = ao2_find(features->dtmf_hooks, dtmf, OBJ_SEARCH_PARTIAL_KEY))) {
2562  enum ast_frame_type frametype = frame->frametype;
2563 
2564  bridge_frame_free(frame);
2565  frame = NULL;
2566 
2567  ao2_cleanup(hook);
2568 
2569  switch (frametype) {
2570  case AST_FRAME_DTMF_BEGIN:
2571  /* Just eat the frame. */
2572  break;
2573  case AST_FRAME_DTMF_END:
2574  ast_bridge_channel_feature_digit(bridge_channel, dtmf[0]);
2575  break;
2576  default:
2577  /* Unexpected frame type. */
2578  ast_assert(0);
2579  break;
2580  }
2581 #ifdef TEST_FRAMEWORK
2582  } else if (frame->frametype == AST_FRAME_DTMF_END) {
2583  /* Only transmit this event on DTMF end or else every DTMF
2584  * press will result in the event being broadcast twice
2585  */
2586  ast_test_suite_event_notify("FEATURE_DETECTION", "Result: fail");
2587 #endif
2588  }
2589 
2590  return frame;
2591 }
struct ast_bridge_channel::@233 dtmf_hook_state
struct ast_bridge_features * features
Structure that contains features information.
struct ao2_container * dtmf_hooks
void ast_bridge_channel_feature_digit(struct ast_bridge_channel *bridge_channel, int digit)
Add a DTMF digit to the collected digits to match against DTMF features.
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
char collected[MAXIMUM_DTMF_FEATURE_STRING]
struct ast_frame_subclass subclass
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1120
struct ast_bridge_hook_dtmf_parms dtmf
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
ast_frame_type
Frame types.
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
enum ast_frame_type frametype
static void bridge_frame_free(struct ast_frame *frame)

◆ bridge_handle_trip()

static void bridge_handle_trip ( struct ast_bridge_channel bridge_channel)
static

Definition at line 2608 of file bridge_channel.c.

References ast_bridge_channel_kick(), ast_bridge_channel_lock_bridge(), ast_bridge_channel_stream_map(), ast_bridge_unlock, ast_channel_call_forward(), ast_channel_is_multistream(), ast_channel_publish_dial(), ast_channel_publish_dial_forward(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_read_stream(), ast_read_stream_noaudio(), ast_strlen_zero, ast_bridge_channel::bridge, bridge_channel_write_frame(), bridge_frame_free(), bridge_handle_dtmf(), ast_bridge_channel::chan, controls, ast_bridge_features::dtmf_passthrough, ast_bridge_channel::features, ast_frame::frametype, ast_frame_subclass::integer, ast_bridge_features::mute, NULL, ast_frame::stream_num, ast_bridge_technology::stream_topology_changed, ast_bridge_technology::stream_topology_request_change, ast_frame::subclass, and ast_bridge::technology.

Referenced by bridge_channel_wait().

2609 {
2610  struct ast_frame *frame;
2611  int blocked;
2612 
2613  if (!ast_strlen_zero(ast_channel_call_forward(bridge_channel->chan))) {
2614  /* TODO If early bridging is ever used by anything other than ARI,
2615  * it's important that we actually attempt to handle the call forward
2616  * attempt, as well as expand features on a bridge channel to allow/disallow
2617  * call forwarding. For now, all we do is raise an event, showing that
2618  * a call forward is being attempted.
2619  */
2620  ast_channel_publish_dial_forward(NULL, bridge_channel->chan, NULL, NULL, "CANCEL",
2621  ast_channel_call_forward(bridge_channel->chan));
2622  }
2623 
2624  if (bridge_channel->features->mute) {
2625  frame = ast_read_stream_noaudio(bridge_channel->chan);
2626  } else {
2627  frame = ast_read_stream(bridge_channel->chan);
2628  }
2629 
2630  if (!frame) {
2631  ast_bridge_channel_kick(bridge_channel, 0);
2632  return;
2633  }
2634 
2635  if (!ast_channel_is_multistream(bridge_channel->chan)) {
2636  /* This may not be initialized by non-multistream channel drivers */
2637  frame->stream_num = -1;
2638  }
2639 
2640  switch (frame->frametype) {
2641  case AST_FRAME_CONTROL:
2642  switch (frame->subclass.integer) {
2644  case AST_CONTROL_BUSY:
2645  ast_channel_publish_dial(NULL, bridge_channel->chan, NULL, controls[frame->subclass.integer]);
2646  break;
2647  case AST_CONTROL_HANGUP:
2648  ast_bridge_channel_kick(bridge_channel, 0);
2649  bridge_frame_free(frame);
2650  return;
2651  case AST_CONTROL_RINGING:
2652  case AST_CONTROL_PROGRESS:
2654  case AST_CONTROL_ANSWER:
2655  ast_channel_publish_dial(NULL, bridge_channel->chan, NULL, controls[frame->subclass.integer]);
2656  break;
2658  ast_bridge_channel_lock_bridge(bridge_channel);
2659  blocked = bridge_channel->bridge->technology->stream_topology_request_change
2660  && bridge_channel->bridge->technology->stream_topology_request_change(
2661  bridge_channel->bridge, bridge_channel);
2662  ast_bridge_unlock(bridge_channel->bridge);
2663  if (blocked) {
2664  /*
2665  * Topology change was intercepted by the bridge technology
2666  * so drop frame.
2667  */
2668  bridge_frame_free(frame);
2669  return;
2670  }
2671  break;
2673  /*
2674  * If a stream topology has changed then the bridge_channel's
2675  * media mapping needs to be updated.
2676  */
2677  ast_bridge_channel_lock_bridge(bridge_channel);
2678  if (bridge_channel->bridge->technology->stream_topology_changed) {
2679  bridge_channel->bridge->technology->stream_topology_changed(
2680  bridge_channel->bridge, bridge_channel);
2681  } else {
2682  ast_bridge_channel_stream_map(bridge_channel);
2683  }
2684  ast_bridge_unlock(bridge_channel->bridge);
2685  break;
2686  default:
2687  break;
2688  }
2689  break;
2690  case AST_FRAME_DTMF_BEGIN:
2691  case AST_FRAME_DTMF_END:
2692  frame = bridge_handle_dtmf(bridge_channel, frame);
2693  if (!frame) {
2694  return;
2695  }
2696  if (!bridge_channel->features->dtmf_passthrough) {
2697  bridge_frame_free(frame);
2698  return;
2699  }
2700  break;
2701  default:
2702  break;
2703  }
2704 
2705  /* Simply write the frame out to the bridge technology. */
2706  bridge_channel_write_frame(bridge_channel, frame);
2707  bridge_frame_free(frame);
2708 }
static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
struct ast_bridge_features * features
int ast_channel_is_multistream(struct ast_channel *chan)
Determine if a channel is multi-stream capable.
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
int(* stream_topology_request_change)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Callback for when a request has been made to change a stream topology on a channel.
struct ast_frame * ast_read_stream(struct ast_channel *chan)
Reads a frame, but does not filter to just the default streams.
Definition: channel.c:4307
void(* stream_topology_changed)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Callback for when a stream topology changes on the channel.
static const char * controls[]
#define NULL
Definition: resample.c:96
const char * ast_channel_call_forward(const struct ast_channel *chan)
void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel)
Maps a channel&#39;s stream topology to and from the bridge.
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_frame_subclass subclass
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_bridge_technology * technology
Definition: bridge.h:363
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
struct ast_frame * ast_read_stream_noaudio(struct ast_channel *chan)
Reads a frame, but does not filter to just the default streams, returning AST_FRAME_NULL frame if aud...
Definition: channel.c:4317
unsigned int dtmf_passthrough
void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ast_channel * chan
Data structure associated with a single frame of data.
enum ast_frame_type frametype
static void bridge_frame_free(struct ast_frame *frame)
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
static struct ast_frame * bridge_handle_dtmf(struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Internal function to handle DTMF from a channel.

◆ bridge_sync_cleanup()

static void bridge_sync_cleanup ( struct bridge_sync sync_struct)
static

Clean up a syncrhonization bridge object.

This frees fields within the synchronization object and removes it from the list of active synchronization objects.

Since synchronization objects are stack-allocated, it is vital that this is called before the synchronization object goes out of scope.

Parameters
sync_structSynchronization object to clean up.

Definition at line 147 of file bridge_channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sem_destroy(), bridge_sync::id, bridge_sync::list, and bridge_sync::sem.

Referenced by bridge_channel_queue_action_data_sync().

148 {
149  struct bridge_sync *iter;
150 
153  if (iter->id == sync_struct->id) {
155  break;
156  }
157  }
160 
161  ast_sem_destroy(&sync_struct->sem);
162 }
struct ast_sem sem
int ast_sem_destroy(struct ast_sem *sem)
Destroy a semaphore.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
List holding active synchronous action objects.
struct bridge_sync::@354 list
Synchronous bridge action object.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
unsigned int id

◆ bridge_sync_init()

static void bridge_sync_init ( struct bridge_sync sync_struct,
unsigned int  id 
)
static

initialize a synchronous bridge object.

This both initializes the structure and adds it to the list of synchronization structures.

Parameters
sync_structThe synchronization object to initialize.
idID to assign to the synchronization object.

Definition at line 124 of file bridge_channel.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sem_init(), sync_payload::id, bridge_sync::id, and bridge_sync::sem.

Referenced by bridge_channel_queue_action_data_sync().

125 {
126  memset(sync_struct, 0, sizeof(*sync_struct));
127  sync_struct->id = id;
128  ast_sem_init(&sync_struct->sem, 0, 0);
129 
131  AST_RWLIST_INSERT_TAIL(&sync_structs, sync_struct, list);
133 }
struct ast_sem sem
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
List holding active synchronous action objects.
struct bridge_sync::@354 list
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
Initialize a semaphore.
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
enum queue_result id
Definition: app_queue.c:1507
unsigned int id

◆ bridge_sync_signal()

static void bridge_sync_signal ( struct bridge_sync sync_struct)
static

Signal that waiting for a synchronous bridge action is no longer necessary.

This may occur for several reasons

  • The synchronous bridge action has completed.
  • The bridge channel has been removed from the bridge.
  • The synchronous bridge action could not be queued.
Parameters
sync_structSynchronization object corresponding to the bridge action.

Definition at line 206 of file bridge_channel.c.

References ast_sem_post(), and bridge_sync::sem.

Referenced by bridge_frame_free().

207 {
208  ast_sem_post(&sync_struct->sem);
209 }
struct ast_sem sem
int ast_sem_post(struct ast_sem *sem)
Increments the semaphore, unblocking a waiter if necessary.

◆ bridge_sync_wait()

static void bridge_sync_wait ( struct bridge_sync sync_struct)
static

Wait for a synchronous bridge action to complete.

Parameters
sync_structSynchronization object corresponding to the bridge action.

Definition at line 185 of file bridge_channel.c.

References ast_samp2tv(), ast_sem_timedwait(), ast_tvadd(), ast_tvnow(), PLAYBACK_TIMEOUT, and bridge_sync::sem.

Referenced by bridge_channel_queue_action_data_sync().

186 {
187  struct timeval timeout_val = ast_tvadd(ast_tvnow(), ast_samp2tv(PLAYBACK_TIMEOUT, 1000));
188  struct timespec timeout_spec = {
189  .tv_sec = timeout_val.tv_sec,
190  .tv_nsec = timeout_val.tv_usec * 1000,
191  };
192 
193  ast_sem_timedwait(&sync_struct->sem, &timeout_spec);
194 }
#define PLAYBACK_TIMEOUT
Failsafe for synchronous bridge action waiting.
struct ast_sem sem
int ast_sem_timedwait(struct ast_sem *sem, const struct timespec *abs_timeout)
Decrements the semaphore, waiting until abs_timeout.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283

◆ channel_fill_empty_accountcode()

static void channel_fill_empty_accountcode ( struct ast_channel dest,
struct ast_channel src 
)
static

Definition at line 443 of file bridge_channel.c.

References ast_channel_accountcode(), ast_channel_name(), ast_channel_peeraccount(), ast_debug, and ast_strlen_zero.

Referenced by channel_set_empty_accountcodes().

444 {
447  ast_debug(1, "Setting channel %s accountcode with channel %s peeraccount '%s'.\n",
448  ast_channel_name(dest),
450  ast_channel_accountcode_set(dest, ast_channel_peeraccount(src));
451  }
452 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * ast_channel_accountcode(const struct ast_channel *chan)
const char * ast_channel_peeraccount(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)

◆ channel_fill_empty_peeraccount()

static void channel_fill_empty_peeraccount ( struct ast_channel dest,
struct ast_channel src 
)
static

Definition at line 420 of file bridge_channel.c.

References ast_channel_accountcode(), ast_channel_name(), ast_channel_peeraccount(), ast_debug, and ast_strlen_zero.

Referenced by channel_set_empty_accountcodes().

421 {
424  ast_debug(1, "Setting channel %s peeraccount with channel %s accountcode '%s'.\n",
425  ast_channel_name(dest),
427  ast_channel_peeraccount_set(dest, ast_channel_accountcode(src));
428  }
429 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * ast_channel_accountcode(const struct ast_channel *chan)
const char * ast_channel_peeraccount(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)

◆ channel_set_cause()

static int channel_set_cause ( struct ast_channel chan,
int  cause 
)
static

Definition at line 278 of file bridge_channel.c.

References AST_CAUSE_NORMAL_CLEARING, ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_lock, and ast_channel_unlock.

Referenced by ast_bridge_channel_kick(), and ast_bridge_channel_leave_bridge_nolock().

279 {
280  ast_channel_lock(chan);
281  if (cause <= 0) {
282  cause = ast_channel_hangupcause(chan);
283  if (cause <= 0) {
285  }
286  }
287  ast_channel_hangupcause_set(chan, cause);
288  ast_channel_unlock(chan);
289  return cause;
290 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int ast_channel_hangupcause(const struct ast_channel *chan)

◆ channel_set_empty_accountcodes()

static void channel_set_empty_accountcodes ( struct ast_channel c0,
struct ast_channel c1 
)
static

Definition at line 466 of file bridge_channel.c.

References channel_fill_empty_accountcode(), and channel_fill_empty_peeraccount().

Referenced by bridge_channel_update_accountcodes_joining(), and bridge_channel_update_accountcodes_leaving().

467 {
468  /* Set empty peeraccount from the other channel's accountcode. */
471 
472  /* Set empty accountcode from the other channel's peeraccount. */
475 }
static void channel_fill_empty_accountcode(struct ast_channel *dest, struct ast_channel *src)
static void channel_fill_empty_peeraccount(struct ast_channel *dest, struct ast_channel *src)

◆ channel_update_peeraccount()

static void channel_update_peeraccount ( struct ast_channel dest,
struct ast_channel src 
)
static

Definition at line 489 of file bridge_channel.c.

References ast_channel_accountcode(), ast_channel_name(), ast_channel_peeraccount(), and ast_debug.

Referenced by channel_update_peeraccounts().

490 {
491  if (strcmp(ast_channel_accountcode(src), ast_channel_peeraccount(dest))) {
492  ast_debug(1, "Changing channel %s peeraccount '%s' to match channel %s accountcode '%s'.\n",
495  ast_channel_peeraccount_set(dest, ast_channel_accountcode(src));
496  }
497 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * ast_channel_accountcode(const struct ast_channel *chan)
const char * ast_channel_peeraccount(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)

◆ channel_update_peeraccounts()

static void channel_update_peeraccounts ( struct ast_channel c0,
struct ast_channel c1 
)
static

Definition at line 511 of file bridge_channel.c.

References channel_update_peeraccount().

Referenced by bridge_channel_update_accountcodes_joining(), and bridge_channel_update_accountcodes_leaving().

512 {
515 }
static void channel_update_peeraccount(struct ast_channel *dest, struct ast_channel *src)

◆ payload_helper_app()

static int payload_helper_app ( ast_bridge_channel_post_action_data  post_it,
struct ast_bridge_channel bridge_channel,
const char *  app_name,
const char *  app_args,
const char *  moh_class 
)
static

Definition at line 1285 of file bridge_channel.c.

References bridge_run_app::app_args_offset, bridge_run_app::app_name, ast_strlen_zero, BRIDGE_CHANNEL_ACTION_RUN_APP, and bridge_run_app::moh_offset.

Referenced by ast_bridge_channel_queue_app(), and ast_bridge_channel_write_app().

1287 {
1288  struct bridge_run_app *app_data;
1289  size_t len_name = strlen(app_name) + 1;
1290  size_t len_args = ast_strlen_zero(app_args) ? 0 : strlen(app_args) + 1;
1291  size_t len_moh = !moh_class ? 0 : strlen(moh_class) + 1;
1292  size_t len_data = sizeof(*app_data) + len_name + len_args + len_moh;
1293 
1294  /* Fill in application run frame data. */
1295  app_data = alloca(len_data);
1296  app_data->app_args_offset = len_args ? len_name : 0;
1297  app_data->moh_offset = len_moh ? len_name + len_args : 0;
1298  strcpy(app_data->app_name, app_name);/* Safe */
1299  if (len_args) {
1300  strcpy(&app_data->app_name[app_data->app_args_offset], app_args);/* Safe */
1301  }
1302  if (moh_class) {
1303  strcpy(&app_data->app_name[app_data->moh_offset], moh_class);/* Safe */
1304  }
1305 
1306  return post_it(bridge_channel, BRIDGE_CHANNEL_ACTION_RUN_APP, app_data, len_data);
1307 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463

◆ payload_helper_cb()

static int payload_helper_cb ( ast_bridge_channel_post_action_data  post_it,
struct ast_bridge_channel bridge_channel,
enum ast_bridge_channel_custom_callback_option  flags,
ast_bridge_custom_callback_fn  callback,
const void *  payload,
size_t  payload_size 
)
static

Definition at line 1457 of file bridge_channel.c.

References ast_assert, BRIDGE_CHANNEL_ACTION_CALLBACK, bridge_custom_callback::callback, bridge_custom_callback::flags, bridge_custom_callback::payload, bridge_custom_callback::payload_exists, and bridge_custom_callback::payload_size.

Referenced by ast_bridge_channel_queue_callback(), and ast_bridge_channel_write_callback().

1461 {
1462  struct bridge_custom_callback *cb_data;
1463  size_t len_data = sizeof(*cb_data) + (payload ? payload_size : 0);
1464 
1465  /* Sanity check. */
1466  if (!callback) {
1467  ast_assert(0);
1468  return -1;
1469  }
1470 
1471  /* Fill in custom callback frame data. */
1472  cb_data = alloca(len_data);
1473  cb_data->callback = callback;
1474  cb_data->payload_size = payload_size;
1475  cb_data->flags = flags;
1476  cb_data->payload_exists = payload && payload_size;
1477  if (cb_data->payload_exists) {
1478  memcpy(cb_data->payload, payload, payload_size);/* Safe */
1479  }
1480 
1481  return post_it(bridge_channel, BRIDGE_CHANNEL_ACTION_CALLBACK, cb_data, len_data);
1482 }
#define ast_assert(a)
Definition: utils.h:695
ast_bridge_custom_callback_fn callback

◆ payload_helper_park()

static int payload_helper_park ( ast_bridge_channel_post_action_data  post_it,
struct ast_bridge_channel bridge_channel,
const char *  parkee_uuid,
const char *  parker_uuid,
const char *  app_data 
)
static

Definition at line 1531 of file bridge_channel.c.

References bridge_park::app_data_offset, BRIDGE_CHANNEL_ACTION_PARK, bridge_park::parkee_uuid, and bridge_park::parker_uuid_offset.

Referenced by ast_bridge_channel_write_park().

1536 {
1537  struct bridge_park *payload;
1538  size_t len_parkee_uuid = strlen(parkee_uuid) + 1;
1539  size_t len_parker_uuid = strlen(parker_uuid) + 1;
1540  size_t len_app_data = !app_data ? 0 : strlen(app_data) + 1;
1541  size_t len_payload = sizeof(*payload) + len_parker_uuid + len_parkee_uuid + len_app_data;
1542 
1543  payload = alloca(len_payload);
1544  payload->app_data_offset = len_app_data ? len_parkee_uuid + len_parker_uuid : 0;
1545  payload->parker_uuid_offset = len_parkee_uuid;
1546  strcpy(payload->parkee_uuid, parkee_uuid);
1547  strcpy(&payload->parkee_uuid[payload->parker_uuid_offset], parker_uuid);
1548  if (app_data) {
1549  strcpy(&payload->parkee_uuid[payload->app_data_offset], app_data);
1550  }
1551 
1552  return post_it(bridge_channel, BRIDGE_CHANNEL_ACTION_PARK, payload, len_payload);
1553 }
char parkee_uuid[0]

◆ payload_helper_playfile()

static int payload_helper_playfile ( ast_bridge_channel_post_action_data  post_it,
struct ast_bridge_channel bridge_channel,
ast_bridge_custom_play_fn  custom_play,
const char *  playfile,
const char *  moh_class 
)
static

Definition at line 1378 of file bridge_channel.c.

References ast_alloca, BRIDGE_CHANNEL_ACTION_PLAY_FILE, bridge_playfile::custom_play, bridge_playfile::moh_offset, and bridge_playfile::playfile.

Referenced by ast_bridge_channel_queue_playfile(), ast_bridge_channel_queue_playfile_sync(), and ast_bridge_channel_write_playfile().

1380 {
1381  struct bridge_playfile *payload;
1382  size_t len_name = strlen(playfile) + 1;
1383  size_t len_moh = !moh_class ? 0 : strlen(moh_class) + 1;
1384  size_t len_payload = sizeof(*payload) + len_name + len_moh;
1385 
1386  /* Fill in play file frame data. */
1387  payload = ast_alloca(len_payload);
1388  payload->custom_play = custom_play;
1389  payload->moh_offset = len_moh ? len_name : 0;
1390  strcpy(payload->playfile, playfile);/* Safe */
1391  if (moh_class) {
1392  strcpy(&payload->playfile[payload->moh_offset], moh_class);/* Safe */
1393  }
1394 
1395  return post_it(bridge_channel, BRIDGE_CHANNEL_ACTION_PLAY_FILE, payload, len_payload);
1396 }
ast_bridge_custom_play_fn custom_play
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290

◆ run_app_helper()

static int run_app_helper ( struct ast_channel chan,
const char *  app_name,
const char *  app_args 
)
static

Definition at line 1211 of file bridge_channel.c.

References app, ast_app_exec_macro(), ast_app_exec_sub(), ast_free, ast_log, ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), LOG_WARNING, NULL, pbx_exec(), and pbx_findapp().

Referenced by ast_bridge_channel_run_app().

1212 {
1213  int res = 0;
1214 
1215  if (!strcasecmp("Gosub", app_name)) {
1216  ast_app_exec_sub(NULL, chan, app_args, 0);
1217  } else if (!strcasecmp("Macro", app_name)) {
1218  ast_app_exec_macro(NULL, chan, app_args);
1219  } else {
1220  struct ast_app *app;
1221 
1222  app = pbx_findapp(app_name);
1223  if (!app) {
1224  ast_log(LOG_WARNING, "Could not find application (%s)\n", app_name);
1225  } else {
1226  struct ast_str *substituted_args = ast_str_create(16);
1227 
1228  if (substituted_args) {
1229  ast_str_substitute_variables(&substituted_args, 0, chan, app_args);
1230  res = pbx_exec(chan, app, ast_str_buffer(substituted_args));
1231  ast_free(substituted_args);
1232  } else {
1233  ast_log(LOG_WARNING, "Could not substitute application argument variables for %s\n", app_name);
1234  res = pbx_exec(chan, app, app_args);
1235  }
1236  }
1237  }
1238  return res;
1239 }
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
Run a macro on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:273
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
#define ast_free(a)
Definition: astmm.h:182
ast_app: A registered application
Definition: pbx_app.c:45
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:370
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
static const char app[]
Definition: app_mysql.c:62
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ sendtext_safe()

static void sendtext_safe ( struct ast_channel chan,
const struct ast_frame f 
)
static

Definition at line 2409 of file bridge_channel.c.

References ast_free, ast_sendtext(), ast_strndup, ast_frame::data, ast_frame::datalen, ast_frame::ptr, and text.

Referenced by bridge_channel_handle_write().

2410 {
2411  if (f->datalen) {
2412  char *text = f->data.ptr;
2413 
2414  if (text[f->datalen - 1]) {
2415  /* Not zero terminated, we need to allocate */
2416  text = ast_strndup(text, f->datalen);
2417  if (!text) {
2418  return;
2419  }
2420  }
2421 
2422  ast_sendtext(chan, text);
2423 
2424  if (text != f->data.ptr) {
2425  /* Only free if we allocated */
2426  ast_free(text);
2427  }
2428  } else {
2429  /* Special case if the frame length is zero (although I
2430  * am not sure this is possible?) */
2431  ast_sendtext(chan, "");
2432  }
2433 }
char * text
Definition: app_queue.c:1508
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:258
#define ast_free(a)
Definition: astmm.h:182
union ast_frame::@263 data
int ast_sendtext(struct ast_channel *chan, const char *text)
Sends text to a channel.
Definition: channel.c:4854

◆ testsuite_notify_feature_success()

static void testsuite_notify_feature_success ( struct ast_channel chan,
const char *  dtmf 
)
static

Definition at line 1675 of file bridge_channel.c.

References ao2_cleanup, ast_channel_lock, ast_channel_unlock, ast_get_chan_featuremap_config(), ast_get_chan_features_xfer_config(), ast_test_suite_event_notify, ast_featuremap_config::atxfer, ast_features_xfer_config::atxferthreeway, ast_featuremap_config::automixmon, ast_featuremap_config::automon, ast_featuremap_config::blindxfer, ast_featuremap_config::disconnect, and ast_featuremap_config::parkcall.

Referenced by ast_bridge_channel_feature_digit().

1676 {
1677 #ifdef TEST_FRAMEWORK
1678  char *feature = "unknown";
1679  struct ast_featuremap_config *featuremap;
1680  struct ast_features_xfer_config *xfer;
1681 
1682  ast_channel_lock(chan);
1683  featuremap = ast_get_chan_featuremap_config(chan);
1684  xfer = ast_get_chan_features_xfer_config(chan);
1685  ast_channel_unlock(chan);
1686 
1687  if (featuremap) {
1688  if (!strcmp(dtmf, featuremap->blindxfer)) {
1689  feature = "blindxfer";
1690  } else if (!strcmp(dtmf, featuremap->atxfer)) {
1691  feature = "atxfer";
1692  } else if (!strcmp(dtmf, featuremap->disconnect)) {
1693  feature = "disconnect";
1694  } else if (!strcmp(dtmf, featuremap->automon)) {
1695  feature = "automon";
1696  } else if (!strcmp(dtmf, featuremap->automixmon)) {
1697  feature = "automixmon";
1698  } else if (!strcmp(dtmf, featuremap->parkcall)) {
1699  feature = "parkcall";
1700  }
1701  }
1702  if (xfer) {
1703  if (!strcmp(dtmf, xfer->atxferthreeway)) {
1704  feature = "atxferthreeway";
1705  }
1706  }
1707 
1708  ao2_cleanup(featuremap);
1709  ao2_cleanup(xfer);
1710 
1711  ast_test_suite_event_notify("FEATURE_DETECTION",
1712  "Result: success\r\n"
1713  "Feature: %s", feature);
1714 #endif /* TEST_FRAMEWORK */
1715 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Feature configuration relating to transfers.
Configuration for the builtin features.
struct ast_features_xfer_config * ast_get_chan_features_xfer_config(struct ast_channel *chan)
Get the transfer configuration options for a channel.
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_featuremap_config * ast_get_chan_featuremap_config(struct ast_channel *chan)
Get the featuremap configuration options for a channel.

Variable Documentation

◆ controls

const char* controls[]
static

Definition at line 2593 of file bridge_channel.c.

Referenced by bridge_handle_trip().

◆ sync_ids

int sync_ids
static

Counter used for assigning synchronous bridge action IDs.

Definition at line 78 of file bridge_channel.c.

Referenced by bridge_channel_queue_action_data_sync().

◆ sync_structs

struct sync_structs sync_structs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static