Asterisk - The Open Source Telephony Project  18.5.0
Enumerations | Functions
bridge_channel_internal.h File Reference

Private Bridging Channel API. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  bridge_channel_action_type {
  BRIDGE_CHANNEL_ACTION_DTMF_STREAM, BRIDGE_CHANNEL_ACTION_TALKING_START, BRIDGE_CHANNEL_ACTION_TALKING_STOP, BRIDGE_CHANNEL_ACTION_PLAY_FILE,
  BRIDGE_CHANNEL_ACTION_RUN_APP, BRIDGE_CHANNEL_ACTION_CALLBACK, BRIDGE_CHANNEL_ACTION_PARK, BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER,
  BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY = 1000, BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING
}
 

Functions

void bridge_channel_impart_signal (struct ast_channel *chan)
 Signal imparting threads to wake up. More...
 
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)
 
void bridge_channel_queue_deferred_frames (struct ast_bridge_channel *bridge_channel)
 
void bridge_channel_settle_owed_events (struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
 

Detailed Description

Private Bridging Channel API.

Author
Matt Jordan mjord.nosp@m.an@d.nosp@m.igium.nosp@m..com

A private API to manipulate channels in a bridge. These can be called on a channel in a bridge by bridge.c. These functions should not be called elsewhere, including by other members of the Bridging API.

See Also:

Definition in file bridge_channel_internal.h.

Enumeration Type Documentation

◆ bridge_channel_action_type

Enumerator
BRIDGE_CHANNEL_ACTION_DTMF_STREAM 

Bridged channel is to send a DTMF stream out

BRIDGE_CHANNEL_ACTION_TALKING_START 

Bridged channel is to indicate talking start

BRIDGE_CHANNEL_ACTION_TALKING_STOP 

Bridged channel is to indicate talking stop

BRIDGE_CHANNEL_ACTION_PLAY_FILE 

Bridge channel is to play the indicated sound file.

BRIDGE_CHANNEL_ACTION_RUN_APP 

Bridge channel is to run the indicated application.

BRIDGE_CHANNEL_ACTION_CALLBACK 

Bridge channel is to run the custom callback routine.

BRIDGE_CHANNEL_ACTION_PARK 

Bridge channel is to get parked.

BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER 

Bridge channel is to execute a blind transfer.

BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER 

Bridge channel is to execute an attended transfer

BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY 

Bridge reconfiguration deferred technology destruction.

BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING 

Bridge deferred dissolving.

Definition at line 41 of file bridge_channel_internal.h.

41  {
42  /*! Bridged channel is to send a DTMF stream out */
44  /*! Bridged channel is to indicate talking start */
46  /*! Bridged channel is to indicate talking stop */
48  /*! Bridge channel is to play the indicated sound file. */
50  /*! Bridge channel is to run the indicated application. */
52  /*! Bridge channel is to run the custom callback routine. */
54  /*! Bridge channel is to get parked. */
56  /*! Bridge channel is to execute a blind transfer. */
58  /*! Bridge channel is to execute an attended transfer */
60 
61  /*
62  * Bridge actions put after this comment must never be put onto
63  * the bridge_channel wr_queue because they have other resources
64  * that must be freed.
65  */
66 
67  /*! Bridge reconfiguration deferred technology destruction. */
69  /*! Bridge deferred dissolving. */
71 };

Function Documentation

◆ bridge_channel_impart_signal()

void bridge_channel_impart_signal ( struct ast_channel chan)

Signal imparting threads to wake up.

Since
13.9.0
Parameters
chanChannel imparted that we need to signal.
Returns
Nothing

Definition at line 1626 of file bridge.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, bridge_channel_impart_ds_head_signal(), ast_datastore::data, and NULL.

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

1627 {
1628  struct ast_datastore *datastore;
1629 
1630  ast_channel_lock(chan);
1632  if (datastore) {
1634  }
1635  ast_channel_unlock(chan);
1636 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1536
static const struct ast_datastore_info bridge_channel_impart_ds_info
Definition: bridge.c:1576
Structure for a data store object.
Definition: datastore.h:68
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2404
#define NULL
Definition: resample.c:96
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70

◆ 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'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'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_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_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