Asterisk - The Open Source Telephony Project  GIT-master-060ce10
Enumerations | Functions
bridge_channel_internal.h File Reference

Private Bridging Channel API. More...

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:2890
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:2390
#define NULL
Definition: resample.c:96
#define ast_channel_unlock(chan)
Definition: channel.h:2891
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 3147 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().

3148 {
3149  struct ast_bridge_channel *bridge_channel;
3150 
3151  bridge_channel = ao2_alloc(sizeof(struct ast_bridge_channel), bridge_channel_destroy);
3152  if (!bridge_channel) {
3153  return NULL;
3154  }
3155  ast_cond_init(&bridge_channel->cond, NULL);
3156  if (ast_alertpipe_init(bridge_channel->alert_pipe)) {
3157  ao2_ref(bridge_channel, -1);
3158  return NULL;
3159  }
3160  if (bridge) {
3161  bridge_channel->bridge = bridge;
3162  ao2_ref(bridge_channel->bridge, +1);
3163  }
3164 
3165  /* The stream_map is initialized later - see ast_bridge_channel_stream_map */
3166 
3167  return bridge_channel;
3168 }
#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 3106 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().

3107 {
3108  return bridge_channel->in_bridge
3109  && AST_LIST_EMPTY(&bridge_channel->wr_queue);
3110 }
struct ast_bridge_channel::@224 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 2898 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().

2899 {
2900  int res = 0;
2901  uint8_t indicate_src_change = 0;
2902  struct ast_bridge_features *channel_features;
2903  struct ast_channel *swap;
2904 
2905  ast_debug(1, "Bridge %s: %p(%s) is joining\n",
2906  bridge_channel->bridge->uniqueid,
2907  bridge_channel, ast_channel_name(bridge_channel->chan));
2908 
2909  /*
2910  * Directly locking the bridge is safe here because nobody else
2911  * knows about this bridge_channel yet.
2912  */
2913  ast_bridge_lock(bridge_channel->bridge);
2914 
2915  ast_channel_lock(bridge_channel->chan);
2916 
2917  bridge_channel->read_format = ao2_bump(ast_channel_readformat(bridge_channel->chan));
2918  bridge_channel->write_format = ao2_bump(ast_channel_writeformat(bridge_channel->chan));
2919 
2920  /* Make sure we're still good to be put into a bridge */
2921  if (ast_channel_internal_bridge(bridge_channel->chan)
2922  || ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_ZOMBIE)) {
2923  ast_channel_unlock(bridge_channel->chan);
2924  ast_bridge_unlock(bridge_channel->bridge);
2925  ast_debug(1, "Bridge %s: %p(%s) failed to join Bridge\n",
2926  bridge_channel->bridge->uniqueid,
2927  bridge_channel,
2928  ast_channel_name(bridge_channel->chan));
2929  return -1;
2930  }
2931  ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
2932 
2933  /* Attach features requested by the channel */
2934  channel_features = ast_channel_feature_hooks_get(bridge_channel->chan);
2935  if (channel_features) {
2936  ast_bridge_features_merge(bridge_channel->features, channel_features);
2937  }
2938  ast_channel_unlock(bridge_channel->chan);
2939 
2940  /* Add the jitterbuffer if the channel requires it */
2941  ast_jb_enable_for_channel(bridge_channel->chan);
2942 
2943  if (!bridge_channel->bridge->callid) {
2944  bridge_channel->bridge->callid = ast_read_threadstorage_callid();
2945  }
2946 
2947  /* Take the swap channel ref from the bridge_channel struct. */
2948  swap = bridge_channel->swap;
2949 
2950  if (bridge_channel_internal_push(bridge_channel)) {
2951  int cause = bridge_channel->bridge->cause;
2952 
2953  ast_bridge_unlock(bridge_channel->bridge);
2954  ast_bridge_channel_kick(bridge_channel, cause);
2955  ast_bridge_channel_lock_bridge(bridge_channel);
2956  ast_bridge_features_remove(bridge_channel->features,
2958  bridge_channel_dissolve_check(bridge_channel);
2959  res = -1;
2960  }
2961  bridge_reconfigured(bridge_channel->bridge, !bridge_channel->inhibit_colp);
2962 
2963  if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2964  /*
2965  * Indicate a source change since this channel is entering the
2966  * bridge system only if the bridge technology is not MULTIMIX
2967  * capable. The MULTIMIX technology has already done it.
2968  */
2969  if (!(bridge_channel->bridge->technology->capabilities
2971  indicate_src_change = 1;
2972  }
2973 
2974  bridge_channel_impart_signal(bridge_channel->chan);
2975  ast_bridge_unlock(bridge_channel->bridge);
2976 
2977  /* Must release any swap ref after unlocking the bridge. */
2978  ao2_t_cleanup(swap, "Bridge push with swap successful");
2979  swap = NULL;
2980 
2981  if (indicate_src_change) {
2982  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
2983  }
2984 
2986 
2987  while (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2988  /* Wait for something to do. */
2989  bridge_channel_wait(bridge_channel);
2990  }
2991 
2992  /* Force a timeout on any accumulated DTMF hook digits. */
2993  ast_bridge_channel_feature_digit(bridge_channel, 0);
2994 
2996  ast_bridge_channel_lock_bridge(bridge_channel);
2997  }
2998 
2999  bridge_channel_internal_pull(bridge_channel);
3000  bridge_channel_settle_owed_events(bridge_channel->bridge, bridge_channel);
3001  bridge_reconfigured(bridge_channel->bridge, 1);
3002 
3003  /* Remove ourselves if we are the video source */
3004  ast_bridge_remove_video_src(bridge_channel->bridge, bridge_channel->chan);
3005 
3006  ast_bridge_unlock(bridge_channel->bridge);
3007 
3008  /* Must release any swap ref after unlocking the bridge. */
3009  ao2_t_cleanup(swap, "Bridge push with swap failed or exited immediately");
3010 
3011  /* Complete any active hold before exiting the bridge. */
3012  if (ast_channel_hold_state(bridge_channel->chan) == AST_CONTROL_HOLD) {
3013  ast_debug(1, "Channel %s simulating UNHOLD for bridge end.\n",
3014  ast_channel_name(bridge_channel->chan));
3015  ast_indicate(bridge_channel->chan, AST_CONTROL_UNHOLD);
3016  }
3017 
3018  /* Complete any partial DTMF digit before exiting the bridge. */
3019  if (ast_channel_sending_dtmf_digit(bridge_channel->chan)) {
3020  ast_channel_end_dtmf(bridge_channel->chan,
3021  ast_channel_sending_dtmf_digit(bridge_channel->chan),
3022  ast_channel_sending_dtmf_tv(bridge_channel->chan), "bridge end");
3023  }
3024 
3025  /* Complete any T.38 session before exiting the bridge. */
3026  if (ast_channel_is_t38_active(bridge_channel->chan)) {
3027  struct ast_control_t38_parameters t38_parameters = {
3029  };
3030 
3031  ast_debug(1, "Channel %s simulating T.38 terminate for bridge end.\n",
3032  ast_channel_name(bridge_channel->chan));
3034  &t38_parameters, sizeof(t38_parameters));
3035  }
3036 
3037  /* Indicate a source change since this channel is leaving the bridge system. */
3038  ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
3039 
3040  /*
3041  * Wait for any dual redirect to complete.
3042  *
3043  * Must be done while "still in the bridge" for ast_async_goto()
3044  * to work right.
3045  */
3047  sched_yield();
3048  }
3049  ast_channel_lock(bridge_channel->chan);
3050  ast_channel_internal_bridge_set(bridge_channel->chan, NULL);
3051  ast_channel_unlock(bridge_channel->chan);
3052 
3053  ast_bridge_channel_restore_formats(bridge_channel);
3054 
3055  return res;
3056 }
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:4291
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:4667
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:1932
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:444
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:10958
#define ast_channel_unlock(chan)
Definition: channel.h:2891
#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:10924
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 2174 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().

2175 {
2176  struct ast_bridge *bridge = bridge_channel->bridge;
2177 
2178  if (!bridge_channel->in_bridge) {
2179  return;
2180  }
2181  bridge_channel->in_bridge = 0;
2182 
2183  ast_debug(1, "Bridge %s: pulling %p(%s)\n",
2184  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2185 
2186  ast_verb(3, "Channel %s left '%s' %s-bridge <%s>\n",
2187  ast_channel_name(bridge_channel->chan),
2188  bridge->technology->name,
2189  bridge->v_table->name,
2190  bridge->uniqueid);
2191 
2192  if (!bridge_channel->just_joined) {
2193  /* Tell the bridge technology we are leaving so they tear us down */
2194  ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology\n",
2195  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
2196  bridge->technology->name);
2197  if (bridge->technology->leave) {
2198  bridge->technology->leave(bridge, bridge_channel);
2199  }
2200  }
2201 
2202  /* Remove channel from the bridge */
2203  if (!bridge_channel->suspended) {
2204  --bridge->num_active;
2205  }
2207  --bridge->num_lonely;
2208  }
2209  --bridge->num_channels;
2210  AST_LIST_REMOVE(&bridge->channels, bridge_channel, entry);
2211 
2212  bridge_channel_dissolve_check(bridge_channel);
2213  bridge->v_table->pull(bridge, bridge_channel);
2214 
2215  ast_bridge_channel_clear_roles(bridge_channel);
2216 
2217  /* If we are not going to be hung up after leaving a bridge, and we were an
2218  * outgoing channel, clear the outgoing flag.
2219  */
2220  if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING)
2221  && (ast_channel_is_leaving_bridge(bridge_channel->chan)
2222  || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) {
2223  ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan));
2224  ast_channel_clear_flag(bridge_channel->chan, AST_FLAG_OUTGOING);
2225  }
2226 
2227  bridge->reconfigured = 1;
2228  ast_bridge_publish_leave(bridge, bridge_channel->chan);
2229 }
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:11089
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:455
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:444
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:10608
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 2311 of file bridge_channel.c.

References bridge_channel_internal_push_full().

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

2312 {
2313  return bridge_channel_internal_push_full(bridge_channel, 0);
2314 }
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 2231 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().

2232 {
2233  struct ast_bridge *bridge = bridge_channel->bridge;
2234  struct ast_bridge_channel *swap;
2235 
2236  ast_assert(!bridge_channel->in_bridge);
2237 
2238  swap = bridge_find_channel(bridge, bridge_channel->swap);
2239  bridge_channel->swap = NULL;
2240 
2241  if (swap) {
2242  ast_debug(1, "Bridge %s: pushing %p(%s) by swapping with %p(%s)\n",
2243  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
2244  swap, ast_channel_name(swap->chan));
2245  } else {
2246  ast_debug(1, "Bridge %s: pushing %p(%s)\n",
2247  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2248  }
2249 
2250  /* Add channel to the bridge */
2251  if (bridge->dissolved
2252  || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2253  || (swap && swap->state != BRIDGE_CHANNEL_STATE_WAIT)
2254  || bridge->v_table->push(bridge, bridge_channel, swap)) {
2255  ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n",
2256  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2257  return -1;
2258  }
2259 
2260  ast_bridge_channel_establish_roles(bridge_channel);
2261 
2262  if (swap) {
2264 
2265  /* This flag is cleared so the act of this channel leaving does not cause it to dissolve if need be */
2267 
2268  if (optimized) {
2270  }
2273 
2275  }
2276 
2277  bridge_channel->in_bridge = 1;
2278  bridge_channel->just_joined = 1;
2279  AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
2280  ++bridge->num_channels;
2282  ++bridge->num_lonely;
2283  }
2284  if (!bridge_channel->suspended) {
2285  ++bridge->num_active;
2286  }
2287 
2288  ast_verb(3, "Channel %s %s%s%s '%s' %s-bridge <%s>\n",
2289  ast_channel_name(bridge_channel->chan),
2290  swap ? "swapped with " : "joined",
2291  swap ? ast_channel_name(swap->chan) : "",
2292  swap ? " into" : "",
2293  bridge->technology->name,
2294  bridge->v_table->name,
2295  bridge->uniqueid);
2296 
2297  ast_bridge_publish_enter(bridge, bridge_channel->chan, swap ? swap->chan : NULL);
2298 
2299  /* Clear any BLINDTRANSFER,ATTENDEDTRANSFER and FORWARDERNAME since the transfer has completed. */
2300  pbx_builtin_setvar_helper(bridge_channel->chan, "BLINDTRANSFER", NULL);
2301  pbx_builtin_setvar_helper(bridge_channel->chan, "ATTENDEDTRANSFER", NULL);
2302  pbx_builtin_setvar_helper(bridge_channel->chan, "FORWARDERNAME", NULL);
2303 
2304  /* Wake up the bridge channel thread to reevaluate any interval timers. */
2305  ast_queue_frame(bridge_channel->chan, &ast_null_frame);
2306 
2307  bridge->reconfigured = 1;
2308  return 0;
2309 }
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:650
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:455
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:444
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:1135
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 3084 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().

3086 {
3087  RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
3088  char unbridged_chan_name[AST_CHANNEL_NAME];
3089 
3090  ast_channel_lock(transferee);
3091  transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
3092  ast_channel_unlock(transferee);
3093 
3094  if (!transferee_bridge_channel) {
3095  return -1;
3096  }
3097 
3098  ast_copy_string(unbridged_chan_name, ast_channel_name(unbridged_chan),
3099  sizeof(unbridged_chan_name));
3100 
3101  return bridge_channel_queue_action_data(transferee_bridge_channel,
3102  BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, unbridged_chan_name,
3103  sizeof(unbridged_chan_name));
3104 }
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:851
#define ast_channel_unlock(chan)
Definition: channel.h:2891
#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:10640
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 3058 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().

3061 {
3062  RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
3063  struct blind_transfer_data blind_data;
3064 
3065  ast_channel_lock(transferee);
3066  transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
3067  ast_channel_unlock(transferee);
3068 
3069  if (!transferee_bridge_channel) {
3070  return -1;
3071  }
3072 
3073  if (new_channel_cb) {
3074  new_channel_cb(transferee, user_data, AST_BRIDGE_TRANSFER_SINGLE_PARTY);
3075  }
3076 
3077  ast_copy_string(blind_data.exten, exten, sizeof(blind_data.exten));
3078  ast_copy_string(blind_data.context, context, sizeof(blind_data.context));
3079 
3080  return bridge_channel_queue_action_data(transferee_bridge_channel,
3081  BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, &blind_data, sizeof(blind_data));
3082 }
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:851
#define ast_channel_unlock(chan)
Definition: channel.h:2891
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:10640
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 850 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().

851 {
852  bridge_channel->suspended = 1;
853  if (bridge_channel->in_bridge) {
854  --bridge_channel->bridge->num_active;
855  }
856 
857  /* Get technology bridge threads off of the channel. */
858  if (bridge_channel->bridge->technology->suspend) {
859  bridge_channel->bridge->technology->suspend(bridge_channel->bridge, bridge_channel);
860  }
861 }
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 888 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().

889 {
890  bridge_channel->suspended = 0;
891  if (bridge_channel->in_bridge) {
892  ++bridge_channel->bridge->num_active;
893  }
894 
895  /* Wake technology bridge threads to take care of channel again. */
896  if (bridge_channel->bridge->technology->unsuspend) {
897  bridge_channel->bridge->technology->unsuspend(bridge_channel->bridge, bridge_channel);
898  }
899 
900  /* Wake suspended channel. */
901  ast_bridge_channel_lock(bridge_channel);
902  ast_cond_signal(&bridge_channel->cond);
903  ast_bridge_channel_unlock(bridge_channel);
904 }
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 826 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().

827 {
828  struct ast_frame *frame;
829 
830  ast_bridge_channel_lock(bridge_channel);
831  ast_channel_lock(bridge_channel->chan);
832  while ((frame = AST_LIST_REMOVE_HEAD(&bridge_channel->deferred_queue, frame_list))) {
833  ast_queue_frame_head(bridge_channel->chan, frame);
834  ast_frfree(frame);
835  }
836  ast_channel_unlock(bridge_channel->chan);
837  ast_bridge_channel_unlock(bridge_channel);
838 }
#define ast_channel_lock(chan)
Definition: channel.h:2890
#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.
struct ast_bridge_channel::@225 deferred_queue
#define ast_channel_unlock(chan)
Definition: channel.h:2891
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:1140

◆ 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 788 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().

789 {
790  if (bridge_channel->owed.dtmf_digit) {
791  struct ast_frame frame = {
793  .subclass.integer = bridge_channel->owed.dtmf_digit,
794  .src = "Bridge channel owed DTMF",
795  };
796 
797  frame.len = ast_tvdiff_ms(ast_tvnow(), bridge_channel->owed.dtmf_tv);
798  if (frame.len < option_dtmfminduration) {
799  frame.len = option_dtmfminduration;
800  }
801  ast_log(LOG_DTMF, "DTMF end '%c' simulated to bridge %s because %s left. Duration %ld ms.\n",
802  bridge_channel->owed.dtmf_digit, orig_bridge->uniqueid,
803  ast_channel_name(bridge_channel->chan), frame.len);
804  bridge_channel->owed.dtmf_digit = '\0';
805  orig_bridge->technology->write(orig_bridge, NULL, &frame);
806  }
807  if (bridge_channel->owed.t38_terminate) {
808  struct ast_control_t38_parameters t38_parameters = {
810  };
811  struct ast_frame frame = {
813  .subclass.integer = AST_CONTROL_T38_PARAMETERS,
814  .data.ptr = &t38_parameters,
815  .datalen = sizeof(t38_parameters),
816  .src = "Bridge channel owed T.38 terminate",
817  };
818 
819  ast_debug(1, "T.38 terminate simulated to bridge %s because %s left.\n",
820  orig_bridge->uniqueid, ast_channel_name(bridge_channel->chan));
821  bridge_channel->owed.t38_terminate = 0;
822  orig_bridge->technology->write(orig_bridge, NULL, &frame);
823  }
824 }
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:444
#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.
#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
struct ast_bridge_channel::@226 owed