Asterisk - The Open Source Telephony Project GIT-master-f36a736
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)
 
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};
@ BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY
@ BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER
@ BRIDGE_CHANNEL_ACTION_DTMF_STREAM
@ BRIDGE_CHANNEL_ACTION_TALKING_STOP
@ BRIDGE_CHANNEL_ACTION_PLAY_FILE
@ BRIDGE_CHANNEL_ACTION_TALKING_START
@ BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER
@ BRIDGE_CHANNEL_ACTION_CALLBACK
@ BRIDGE_CHANNEL_ACTION_RUN_APP
@ BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING
@ BRIDGE_CHANNEL_ACTION_PARK

Function Documentation

◆ bridge_channel_impart_signal()

void bridge_channel_impart_signal ( struct ast_channel chan)

Definition at line 1582 of file bridge.c.

1583{
1584 struct ast_datastore *datastore;
1585
1586 ast_channel_lock(chan);
1588 if (datastore) {
1590 }
1591 ast_channel_unlock(chan);
1592}
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1494
static const struct ast_datastore_info bridge_channel_impart_ds_info
Definition: bridge.c:1532
#define ast_channel_lock(chan)
Definition: channel.h:2968
#define ast_channel_unlock(chan)
Definition: channel.h:2969
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:2418
#define NULL
Definition: resample.c:96
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, bridge_channel_impart_ds_head_signal(), bridge_channel_impart_ds_info, 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().

◆ bridge_channel_internal_alloc()

struct ast_bridge_channel * bridge_channel_internal_alloc ( struct ast_bridge bridge)

Definition at line 3096 of file bridge_channel.c.

3097{
3098 struct ast_bridge_channel *bridge_channel;
3099
3100 bridge_channel = ao2_alloc(sizeof(struct ast_bridge_channel), bridge_channel_destroy);
3101 if (!bridge_channel) {
3102 return NULL;
3103 }
3104 ast_cond_init(&bridge_channel->cond, NULL);
3105 if (ast_alertpipe_init(bridge_channel->alert_pipe)) {
3106 ao2_ref(bridge_channel, -1);
3107 return NULL;
3108 }
3109 if (bridge) {
3110 bridge_channel->bridge = bridge;
3111 ao2_ref(bridge_channel->bridge, +1);
3112 }
3113
3114 /* The stream_map is initialized later - see ast_bridge_channel_stream_map */
3115
3116 return bridge_channel;
3117}
int ast_alertpipe_init(int alert_pipe[2])
Initialize an alert pipe.
Definition: alertpipe.c:38
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void bridge_channel_destroy(void *obj)
#define ast_cond_init(cond, attr)
Definition: lock.h:201
Structure that contains information regarding a channel in a bridge.
struct ast_bridge * bridge
Bridge this channel is participating in.

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

◆ bridge_channel_internal_allows_optimization()

int bridge_channel_internal_allows_optimization ( struct ast_bridge_channel bridge_channel)

Definition at line 3055 of file bridge_channel.c.

3056{
3057 return bridge_channel->in_bridge
3058 && AST_LIST_EMPTY(&bridge_channel->wr_queue);
3059}
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
struct ast_bridge_channel::@192 wr_queue
unsigned int in_bridge

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

◆ bridge_channel_internal_join()

int bridge_channel_internal_join ( struct ast_bridge_channel bridge_channel)

Definition at line 2820 of file bridge_channel.c.

2821{
2822 int res = 0;
2823 uint8_t indicate_src_change = 0;
2824 struct ast_bridge_features *channel_features;
2825 struct ast_channel *peer;
2826 struct ast_channel *swap;
2827
2828 ast_debug(1, "Bridge %s: %p(%s) is joining\n",
2831
2832 /*
2833 * Directly locking the bridge is safe here because nobody else
2834 * knows about this bridge_channel yet.
2835 */
2837
2840
2841 if (peer) {
2842 struct ast_bridge *peer_bridge;
2843
2844 ast_channel_unlock(bridge_channel->chan);
2845
2846 ast_channel_lock(peer);
2847 peer_bridge = ast_channel_internal_bridge(peer);
2848 ast_channel_unlock(peer);
2849 ast_channel_unref(peer);
2850
2851 /* As we are only doing a pointer comparison we don't need the peer_bridge
2852 * to be reference counted or locked.
2853 */
2854 if (peer_bridge == bridge_channel->bridge) {
2855 ast_bridge_unlock(bridge_channel->bridge);
2856 ast_debug(1, "Bridge %s: %p(%s) denying Bridge join to prevent Local channel loop\n",
2857 bridge_channel->bridge->uniqueid,
2858 bridge_channel,
2859 ast_channel_name(bridge_channel->chan));
2860 return -1;
2861 }
2862
2863 ast_channel_lock(bridge_channel->chan);
2864 }
2865
2866 bridge_channel->read_format = ao2_bump(ast_channel_readformat(bridge_channel->chan));
2867 bridge_channel->write_format = ao2_bump(ast_channel_writeformat(bridge_channel->chan));
2868
2869 /* Make sure we're still good to be put into a bridge */
2870 if (ast_channel_internal_bridge(bridge_channel->chan)
2871 || ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_ZOMBIE)) {
2872 ast_channel_unlock(bridge_channel->chan);
2873 ast_bridge_unlock(bridge_channel->bridge);
2874 ast_debug(1, "Bridge %s: %p(%s) failed to join Bridge\n",
2875 bridge_channel->bridge->uniqueid,
2876 bridge_channel,
2877 ast_channel_name(bridge_channel->chan));
2878 return -1;
2879 }
2880 ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
2881
2882 /* Attach features requested by the channel */
2883 channel_features = ast_channel_feature_hooks_get(bridge_channel->chan);
2884 if (channel_features) {
2885 ast_bridge_features_merge(bridge_channel->features, channel_features);
2886 }
2887 ast_channel_unlock(bridge_channel->chan);
2888
2889 /* Add the jitterbuffer if the channel requires it */
2890 ast_jb_enable_for_channel(bridge_channel->chan);
2891
2892 if (!bridge_channel->bridge->callid) {
2893 bridge_channel->bridge->callid = ast_read_threadstorage_callid();
2894 }
2895
2896 /* Take the swap channel ref from the bridge_channel struct. */
2897 swap = bridge_channel->swap;
2898
2899 if (bridge_channel_internal_push(bridge_channel)) {
2900 int cause = bridge_channel->bridge->cause;
2901
2902 ast_bridge_unlock(bridge_channel->bridge);
2903 ast_bridge_channel_kick(bridge_channel, cause);
2904 ast_bridge_channel_lock_bridge(bridge_channel);
2905 ast_bridge_features_remove(bridge_channel->features,
2907 bridge_channel_dissolve_check(bridge_channel);
2908 res = -1;
2909 }
2910 bridge_reconfigured(bridge_channel->bridge, !bridge_channel->inhibit_colp);
2911
2912 if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2913 /*
2914 * Indicate a source change since this channel is entering the
2915 * bridge system only if the bridge technology is not MULTIMIX
2916 * capable. The MULTIMIX technology has already done it.
2917 */
2918 if (!(bridge_channel->bridge->technology->capabilities
2920 indicate_src_change = 1;
2921 }
2922
2923 bridge_channel_impart_signal(bridge_channel->chan);
2924 ast_bridge_unlock(bridge_channel->bridge);
2925
2926 /* Must release any swap ref after unlocking the bridge. */
2927 ao2_t_cleanup(swap, "Bridge push with swap successful");
2928 swap = NULL;
2929
2930 if (indicate_src_change) {
2931 ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
2932 }
2933
2935
2936 while (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2937 /* Wait for something to do. */
2938 bridge_channel_wait(bridge_channel);
2939 }
2940
2941 /* Force a timeout on any accumulated DTMF hook digits. */
2942 ast_bridge_channel_feature_digit(bridge_channel, 0);
2943
2945 ast_bridge_channel_lock_bridge(bridge_channel);
2946 }
2947
2948 bridge_channel_internal_pull(bridge_channel);
2949 bridge_channel_settle_owed_events(bridge_channel->bridge, bridge_channel);
2950 bridge_reconfigured(bridge_channel->bridge, 1);
2951
2952 /* Remove ourselves if we are the video source */
2953 ast_bridge_remove_video_src(bridge_channel->bridge, bridge_channel->chan);
2954
2955 ast_bridge_unlock(bridge_channel->bridge);
2956
2957 /* Must release any swap ref after unlocking the bridge. */
2958 ao2_t_cleanup(swap, "Bridge push with swap failed or exited immediately");
2959
2960 /* Complete any active hold before exiting the bridge. */
2961 if (ast_channel_hold_state(bridge_channel->chan) == AST_CONTROL_HOLD) {
2962 ast_debug(1, "Channel %s simulating UNHOLD for bridge end.\n",
2963 ast_channel_name(bridge_channel->chan));
2964 ast_indicate(bridge_channel->chan, AST_CONTROL_UNHOLD);
2965 }
2966
2967 /* Complete any partial DTMF digit before exiting the bridge. */
2968 if (ast_channel_sending_dtmf_digit(bridge_channel->chan)) {
2969 ast_channel_end_dtmf(bridge_channel->chan,
2970 ast_channel_sending_dtmf_digit(bridge_channel->chan),
2971 ast_channel_sending_dtmf_tv(bridge_channel->chan), "bridge end");
2972 }
2973
2974 /* Complete any T.38 session before exiting the bridge. */
2975 if (ast_channel_is_t38_active(bridge_channel->chan)) {
2976 struct ast_control_t38_parameters t38_parameters = {
2978 };
2979
2980 ast_debug(1, "Channel %s simulating T.38 terminate for bridge end.\n",
2981 ast_channel_name(bridge_channel->chan));
2983 &t38_parameters, sizeof(t38_parameters));
2984 }
2985
2986 /* Indicate a source change since this channel is leaving the bridge system. */
2987 ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
2988
2989 /*
2990 * Wait for any dual redirect to complete.
2991 *
2992 * Must be done while "still in the bridge" for ast_async_goto()
2993 * to work right.
2994 */
2996 sched_yield();
2997 }
2998 ast_channel_lock(bridge_channel->chan);
2999 ast_channel_internal_bridge_set(bridge_channel->chan, NULL);
3000 ast_channel_unlock(bridge_channel->chan);
3001
3002 ast_bridge_channel_restore_formats(bridge_channel);
3003
3004 return res;
3005}
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
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1935
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags flags)
Remove marked bridge channel feature hooks.
Definition: bridge.c:3501
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition: bridge.h:94
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:3917
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, 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.
static void bridge_channel_wait(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.
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
static void bridge_channel_dissolve_check(struct ast_bridge_channel *bridge_channel)
static void bridge_channel_event_join_leave(struct ast_bridge_channel *bridge_channel, enum ast_bridge_hook_type type)
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
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...
@ BRIDGE_CHANNEL_STATE_WAIT
void bridge_channel_impart_signal(struct ast_channel *chan)
Definition: bridge.c:1582
@ AST_BRIDGE_HOOK_TYPE_JOIN
@ AST_BRIDGE_HOOK_TYPE_LEAVE
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
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:3595
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1403
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_bridge * ast_channel_internal_bridge(const struct ast_channel *chan)
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:10891
struct timeval ast_channel_sending_dtmf_tv(const struct ast_channel *chan)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
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:10925
void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)
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:4672
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_channel_hold_state(const struct ast_channel *chan)
@ AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT
Definition: channel.h:1055
@ AST_FLAG_ZOMBIE
Definition: channel.h:1007
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:4296
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 * ast_channel_readformat(struct ast_channel *chan)
struct ast_channel * ast_local_get_peer(struct ast_channel *ast)
Get the other local channel in the pair.
Definition: core_local.c:276
@ AST_T38_TERMINATED
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_HOLD
@ AST_CONTROL_SRCCHANGE
#define ast_debug(level,...)
Log a DEBUG message.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2298
struct ast_channel * swap
struct ast_format * write_format
struct ast_bridge_features * features
struct ast_channel * chan
struct ast_format * read_format
enum bridge_channel_state state
unsigned int inhibit_colp
Structure that contains features information.
Structure that contains information about a bridge.
Definition: bridge.h:349
ast_callid callid
Definition: bridge.h:361
const ast_string_field uniqueid
Definition: bridge.h:401
int cause
Definition: bridge.h:386
struct ast_bridge_technology * technology
Definition: bridge.h:355
Main Channel structure associated with a channel.
struct ast_bridge_channel * bridge_channel
enum ast_control_t38 request_response
#define ast_test_flag(p, flag)
Definition: utils.h:63

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_unref, 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_local_get_peer(), ast_read_threadstorage_callid(), AST_T38_TERMINATED, ast_test_flag, ast_bridge_channel::bridge, ast_channel::bridge_channel, 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().

◆ bridge_channel_internal_pull()

void bridge_channel_internal_pull ( struct ast_bridge_channel bridge_channel)

Definition at line 2108 of file bridge_channel.c.

2109{
2110 struct ast_bridge *bridge = bridge_channel->bridge;
2111
2112 if (!bridge_channel->in_bridge) {
2113 return;
2114 }
2115 bridge_channel->in_bridge = 0;
2116
2117 ast_debug(1, "Bridge %s: pulling %p(%s)\n",
2118 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2119
2120 ast_verb(3, "Channel %s left '%s' %s-bridge <%s>\n",
2121 ast_channel_name(bridge_channel->chan),
2122 bridge->technology->name,
2123 bridge->v_table->name,
2124 bridge->uniqueid);
2125
2126 if (!bridge_channel->just_joined) {
2127 /* Tell the bridge technology we are leaving so they tear us down */
2128 ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology\n",
2129 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
2130 bridge->technology->name);
2131 if (bridge->technology->leave) {
2132 bridge->technology->leave(bridge, bridge_channel);
2133 }
2134 }
2135
2136 /* Remove channel from the bridge */
2137 if (!bridge_channel->suspended) {
2138 --bridge->num_active;
2139 }
2141 --bridge->num_lonely;
2142 }
2143 --bridge->num_channels;
2144 AST_LIST_REMOVE(&bridge->channels, bridge_channel, entry);
2145
2146 bridge_channel_dissolve_check(bridge_channel);
2147 bridge->v_table->pull(bridge, bridge_channel);
2148
2149 ast_bridge_channel_clear_roles(bridge_channel);
2150
2151 /* If we are not going to be hung up after leaving a bridge, and we were an
2152 * outgoing channel, clear the outgoing flag.
2153 */
2155 && (ast_channel_is_leaving_bridge(bridge_channel->chan)
2156 || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) {
2157 ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan));
2159 }
2160
2161 bridge->reconfigured = 1;
2162 ast_bridge_publish_leave(bridge, bridge_channel->chan);
2163}
@ AST_BRIDGE_CHANNEL_FLAG_LONELY
void ast_bridge_channel_clear_roles(struct ast_bridge_channel *bridge_channel)
Clear all roles from a bridge_channel's role list.
Definition: bridge_roles.c:491
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11056
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:10572
@ AST_FLAG_OUTGOING
Definition: channel.h:1019
#define ast_verb(level,...)
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:856
void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan)
Publish a bridge channel leave event.
unsigned int suspended
unsigned int just_joined
struct ast_flags feature_flags
const char * name
Definition: bridge.h:259
ast_bridge_pull_channel_fn pull
Definition: bridge.h:267
void(* leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Remove a channel from a bridging technology instance for a bridge.
const struct ast_bridge_methods * v_table
Definition: bridge.h:351
unsigned int reconfigured
Definition: bridge.h:388
unsigned int num_active
Definition: bridge.h:375
struct ast_bridge_channels_list channels
Definition: bridge.h:363
unsigned int num_channels
Definition: bridge.h:373
unsigned int num_lonely
Definition: bridge.h:377
Definition: search.h:40

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_methods::name, ast_bridge_technology::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().

◆ bridge_channel_internal_push()

int bridge_channel_internal_push ( struct ast_bridge_channel bridge_channel)

Definition at line 2245 of file bridge_channel.c.

2246{
2247 return bridge_channel_internal_push_full(bridge_channel, 0);
2248}
int bridge_channel_internal_push_full(struct ast_bridge_channel *bridge_channel, int optimized)

References bridge_channel_internal_push_full().

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

◆ bridge_channel_internal_push_full()

int bridge_channel_internal_push_full ( struct ast_bridge_channel bridge_channel,
int  optimized 
)

Definition at line 2165 of file bridge_channel.c.

2166{
2167 struct ast_bridge *bridge = bridge_channel->bridge;
2168 struct ast_bridge_channel *swap;
2169
2170 ast_assert(!bridge_channel->in_bridge);
2171
2172 swap = bridge_find_channel(bridge, bridge_channel->swap);
2173 bridge_channel->swap = NULL;
2174
2175 if (swap) {
2176 ast_debug(1, "Bridge %s: pushing %p(%s) by swapping with %p(%s)\n",
2177 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
2178 swap, ast_channel_name(swap->chan));
2179 } else {
2180 ast_debug(1, "Bridge %s: pushing %p(%s)\n",
2181 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2182 }
2183
2184 /* Add channel to the bridge */
2185 if (bridge->dissolved
2186 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2188 || bridge->v_table->push(bridge, bridge_channel, swap)) {
2189 ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n",
2190 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
2191 return -1;
2192 }
2193
2194 ast_bridge_channel_establish_roles(bridge_channel);
2195
2196 if (swap) {
2198
2199 /* This flag is cleared so the act of this channel leaving does not cause it to dissolve if need be */
2201
2202 if (optimized) {
2204 }
2207
2209 }
2210
2211 bridge_channel->in_bridge = 1;
2212 bridge_channel->just_joined = 1;
2213 AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
2216 ++bridge->num_lonely;
2217 }
2218 if (!bridge_channel->suspended) {
2219 ++bridge->num_active;
2220 }
2221
2222 ast_verb(3, "Channel %s %s%s%s '%s' %s-bridge <%s>\n",
2223 ast_channel_name(bridge_channel->chan),
2224 swap ? "swapped with " : "joined",
2225 swap ? ast_channel_name(swap->chan) : "",
2226 swap ? " into" : "",
2229 bridge->uniqueid);
2230
2231 ast_bridge_publish_enter(bridge, bridge_channel->chan, swap ? swap->chan : NULL);
2232
2233 /* Clear any BLINDTRANSFER,ATTENDEDTRANSFER and FORWARDERNAME since the transfer has completed. */
2234 pbx_builtin_setvar_helper(bridge_channel->chan, "BLINDTRANSFER", NULL);
2235 pbx_builtin_setvar_helper(bridge_channel->chan, "ATTENDEDTRANSFER", NULL);
2236 pbx_builtin_setvar_helper(bridge_channel->chan, "FORWARDERNAME", NULL);
2237
2238 /* Wake up the bridge channel thread to reevaluate any interval timers. */
2239 ast_queue_frame(bridge_channel->chan, &ast_null_frame);
2240
2241 bridge->reconfigured = 1;
2242 return 0;
2243}
static void bridge_channel_cancel_owed_events(struct ast_bridge_channel *bridge_channel)
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).
@ BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE
@ AST_BRIDGE_FLAG_DISSOLVE_EMPTY
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1429
int ast_bridge_channel_establish_roles(struct ast_bridge_channel *bridge_channel)
Clone the roles from a bridge_channel's attached ast_channel onto the bridge_channel's role list.
Definition: bridge_roles.c:443
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1158
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
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.
void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
Publish a bridge channel enter event.
ast_bridge_push_channel_fn push
Definition: bridge.h:265
unsigned int dissolved
Definition: bridge.h:390
struct ast_flags feature_flags
Definition: bridge.h:369
enum ast_channel_state state
#define ast_assert(a)
Definition: utils.h:739
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_clear_flag(p, flag)
Definition: utils.h:77

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::feature_flags, ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge_channel::in_bridge, ast_bridge_channel::just_joined, ast_bridge_methods::name, ast_bridge_technology::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_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().

◆ 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 3033 of file bridge_channel.c.

3035{
3036 RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
3037 char unbridged_chan_name[AST_CHANNEL_NAME];
3038
3039 ast_channel_lock(transferee);
3040 transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
3041 ast_channel_unlock(transferee);
3042
3043 if (!transferee_bridge_channel) {
3044 return -1;
3045 }
3046
3047 ast_copy_string(unbridged_chan_name, ast_channel_name(unbridged_chan),
3048 sizeof(unbridged_chan_name));
3049
3050 return bridge_channel_queue_action_data(transferee_bridge_channel,
3051 BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, unbridged_chan_name,
3052 sizeof(unbridged_chan_name));
3053}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
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 AST_CHANNEL_NAME
Definition: channel.h:173
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10604
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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

◆ 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 3007 of file bridge_channel.c.

3010{
3011 RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
3012 struct blind_transfer_data blind_data;
3013
3014 ast_channel_lock(transferee);
3015 transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
3016 ast_channel_unlock(transferee);
3017
3018 if (!transferee_bridge_channel) {
3019 return -1;
3020 }
3021
3022 if (new_channel_cb) {
3023 new_channel_cb(transferee, user_data, AST_BRIDGE_TRANSFER_SINGLE_PARTY);
3024 }
3025
3026 ast_copy_string(blind_data.exten, exten, sizeof(blind_data.exten));
3027 ast_copy_string(blind_data.context, context, sizeof(blind_data.context));
3028
3029 return bridge_channel_queue_action_data(transferee_bridge_channel,
3030 BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, &blind_data, sizeof(blind_data));
3031}
@ AST_BRIDGE_TRANSFER_SINGLE_PARTY
Definition: bridge.h:1111
Data specifying where a blind transfer is going to.
char exten[AST_MAX_EXTENSION]

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(), voicemailpwcheck::context, blind_transfer_data::context, blind_transfer_data::exten, NULL, and RAII_VAR.

Referenced by ast_bridge_transfer_blind().

◆ bridge_channel_internal_suspend_nolock()

void bridge_channel_internal_suspend_nolock ( struct ast_bridge_channel bridge_channel)

Definition at line 829 of file bridge_channel.c.

830{
831 bridge_channel->suspended = 1;
832 if (bridge_channel->in_bridge) {
833 --bridge_channel->bridge->num_active;
834 }
835
836 /* Get technology bridge threads off of the channel. */
837 if (bridge_channel->bridge->technology->suspend) {
838 bridge_channel->bridge->technology->suspend(bridge_channel->bridge, bridge_channel);
839 }
840}
void(* suspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Suspend a channel on a bridging technology instance for a bridge.

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

◆ bridge_channel_internal_unsuspend_nolock()

void bridge_channel_internal_unsuspend_nolock ( struct ast_bridge_channel bridge_channel)

Definition at line 855 of file bridge_channel.c.

856{
857 bridge_channel->suspended = 0;
858 if (bridge_channel->in_bridge) {
859 ++bridge_channel->bridge->num_active;
860 }
861
862 /* Wake technology bridge threads to take care of channel again. */
863 if (bridge_channel->bridge->technology->unsuspend) {
864 bridge_channel->bridge->technology->unsuspend(bridge_channel->bridge, bridge_channel);
865 }
866
867 /* Wake suspended channel. */
868 ast_bridge_channel_lock(bridge_channel);
869 ast_cond_signal(&bridge_channel->cond);
870 ast_bridge_channel_unlock(bridge_channel);
871}
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define ast_cond_signal(cond)
Definition: lock.h:203
void(* unsuspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Unsuspend a channel on a bridging technology instance for a bridge.

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

◆ bridge_channel_queue_deferred_frames()

void bridge_channel_queue_deferred_frames ( struct ast_bridge_channel bridge_channel)

Definition at line 815 of file bridge_channel.c.

816{
817 struct ast_frame *frame;
818
819 ast_bridge_channel_lock(bridge_channel);
820 ast_channel_lock(bridge_channel->chan);
821 while ((frame = AST_LIST_REMOVE_HEAD(&bridge_channel->deferred_queue, frame_list))) {
822 ast_queue_frame_head(bridge_channel->chan, frame);
823 ast_frfree(frame);
824 }
825 ast_channel_unlock(bridge_channel->chan);
826 ast_bridge_channel_unlock(bridge_channel);
827}
int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to the head of a channel's frame queue.
Definition: channel.c:1163
#define ast_frfree(fr)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
struct ast_bridge_channel::@193 deferred_queue
Data structure associated with a single frame of data.

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

◆ 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 777 of file bridge_channel.c.

778{
779 if (bridge_channel->owed.dtmf_digit) {
780 struct ast_frame frame = {
782 .subclass.integer = bridge_channel->owed.dtmf_digit,
783 .src = "Bridge channel owed DTMF",
784 };
785
786 frame.len = ast_tvdiff_ms(ast_tvnow(), bridge_channel->owed.dtmf_tv);
787 if (frame.len < option_dtmfminduration) {
789 }
790 ast_log(LOG_DTMF, "DTMF end '%c' simulated to bridge %s because %s left. Duration %ld ms.\n",
791 bridge_channel->owed.dtmf_digit, orig_bridge->uniqueid,
792 ast_channel_name(bridge_channel->chan), frame.len);
793 bridge_channel->owed.dtmf_digit = '\0';
794 orig_bridge->technology->write(orig_bridge, NULL, &frame);
795 }
796 if (bridge_channel->owed.t38_terminate) {
797 struct ast_control_t38_parameters t38_parameters = {
799 };
800 struct ast_frame frame = {
802 .subclass.integer = AST_CONTROL_T38_PARAMETERS,
803 .data.ptr = &t38_parameters,
804 .datalen = sizeof(t38_parameters),
805 .src = "Bridge channel owed T.38 terminate",
806 };
807
808 ast_debug(1, "T.38 terminate simulated to bridge %s because %s left.\n",
809 orig_bridge->uniqueid, ast_channel_name(bridge_channel->chan));
810 bridge_channel->owed.t38_terminate = 0;
811 orig_bridge->technology->write(orig_bridge, NULL, &frame);
812 }
813}
#define ast_log
Definition: astobj2.c:42
unsigned int option_dtmfminduration
Definition: options.c:83
@ AST_FRAME_DTMF_END
@ AST_FRAME_CONTROL
#define LOG_DTMF
struct ast_bridge_channel::@194 owed
struct timeval dtmf_tv
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.
enum ast_frame_type frametype
const char * src
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

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