Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Functions
bridge_internal.h File Reference

Private Bridging API. More...

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

Go to the source code of this file.

Functions

struct ast_bridgebridge_alloc (size_t size, const struct ast_bridge_methods *v_table)
 
struct ast_bridgebridge_base_init (struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
 Initialize the base class of the bridge. More...
 
void bridge_dissolve (struct ast_bridge *bridge, int cause)
 
void bridge_do_merge (struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, unsigned int num_kick, unsigned int optimized)
 
int bridge_do_move (struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
 
struct ast_bridge_channelbridge_find_channel (struct ast_bridge *bridge, struct ast_channel *chan)
 
void bridge_merge_inhibit_nolock (struct ast_bridge *bridge, int request)
 
void bridge_reconfigured (struct ast_bridge *bridge, unsigned int colp_update)
 
struct ast_bridgebridge_register (struct ast_bridge *bridge)
 Register the new bridge with the system. More...
 

Detailed Description

Private Bridging API.

Functions in this file are intended to be used by the Bridging API, bridge mixing technologies, and bridge sub-classes. Users of bridges that do not fit those three categories should not use the API defined in this file.

Author
Mark Michelson mmich.nosp@m.elso.nosp@m.n@dig.nosp@m.ium..nosp@m.com

See Also:

Definition in file bridge_internal.h.

Function Documentation

◆ bridge_alloc()

struct ast_bridge * bridge_alloc ( size_t  size,
const struct ast_bridge_methods v_table 
)

Definition at line 747 of file bridge.c.

748{
749 struct ast_bridge *bridge;
750
751 /* Check v_table that all methods are present. */
752 if (!v_table
753 || !v_table->name
754 || !v_table->destroy
756 || !v_table->push
757 || !v_table->pull
760 ast_log(LOG_ERROR, "Virtual method table for bridge class %s not complete.\n",
761 v_table && v_table->name ? v_table->name : "<unknown>");
762 ast_assert(0);
763 return NULL;
764 }
765
766 bridge = ao2_alloc(size, destroy_bridge);
767 if (!bridge) {
768 return NULL;
769 }
770
771 if (ast_string_field_init(bridge, 80)) {
772 ao2_cleanup(bridge);
773 return NULL;
774 }
775
776 bridge->v_table = v_table;
777
779
780 return bridge;
781}
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void destroy_bridge(void *obj)
Definition: bridge.c:659
@ AST_MEDIA_TYPE_END
Definition: codec.h:36
#define LOG_ERROR
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
ast_bridge_dissolving_fn dissolving
Definition: bridge.h:267
ast_bridge_push_channel_fn push
Definition: bridge.h:269
const char * name
Definition: bridge.h:263
ast_bridge_notify_masquerade_fn notify_masquerade
Definition: bridge.h:273
ast_bridge_destructor_fn destroy
Definition: bridge.h:265
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:275
ast_bridge_pull_channel_fn pull
Definition: bridge.h:271
Structure that contains information about a bridge.
Definition: bridge.h:353
struct ast_vector_int media_types
Definition: bridge.h:408
const struct ast_bridge_methods * v_table
Definition: bridge.h:355
#define ast_assert(a)
Definition: utils.h:739
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References ao2_alloc, ao2_cleanup, ast_assert, ast_log, AST_MEDIA_TYPE_END, ast_string_field_init, AST_VECTOR_INIT, ast_bridge_methods::destroy, destroy_bridge(), ast_bridge_methods::dissolving, ast_bridge_methods::get_merge_priority, LOG_ERROR, ast_bridge::media_types, ast_bridge_methods::name, ast_bridge_methods::notify_masquerade, NULL, ast_bridge_methods::pull, ast_bridge_methods::push, and ast_bridge::v_table.

Referenced by ast_bridge_base_new(), ast_bridge_basic_new(), bridge_agent_hold_new(), bridge_parking_new(), and bridge_stasis_new().

◆ bridge_base_init()

struct ast_bridge * bridge_base_init ( struct ast_bridge self,
uint32_t  capabilities,
unsigned int  flags,
const char *  creator,
const char *  name,
const char *  id 
)

Initialize the base class of the bridge.

Parameters
selfBridge to operate upon. (Tolerates a NULL pointer)
capabilitiesThe capabilities that we require to be used on the bridge
flagsFlags that will alter the behavior of the bridge
creatorEntity that created the bridge (optional)
nameName given to the bridge by its creator (optional, requires named creator)
idUnique ID given to the bridge by its creator (optional)
Returns
self on success
Return values
NULLon failure, self is already destroyed

Example usage:

struct ast_bridge *bridge;
bridge = bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table);
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:988
@ AST_BRIDGE_CAPABILITY_1TO1MIX
Definition: bridge.h:96
@ AST_BRIDGE_FLAG_DISSOLVE_HANGUP
struct ast_bridge * bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Initialize the base class of the bridge.
Definition: bridge.c:783
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:747

This creates a no frills two party bridge that will be destroyed once one of the channels hangs up.

Definition at line 783 of file bridge.c.

784{
785 char uuid_hold[AST_UUID_STR_LEN];
786
787 if (!self) {
788 return NULL;
789 }
790
791 {
792 /*
793 * We need to ensure that another bridge with the same uniqueid
794 * doesn't get created before the previous bridge's destructor
795 * has run and deleted the existing topic.
796 */
798 if (!ast_strlen_zero(id)) {
799 if (ast_bridge_topic_exists(id)) {
800 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
801 BRIDGE_PRINTF_VARS(self));
802 ast_bridge_destroy(self, 0);
803 return NULL;
804 }
805 ast_string_field_set(self, uniqueid, id);
806 } else {
808 ast_string_field_set(self, uniqueid, uuid_hold);
809 }
810 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
811 if (bridge_topics_init(self) != 0) {
812 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": Could not initialize topics\n",
813 BRIDGE_PRINTF_VARS(self));
814 ao2_ref(self, -1);
815 return NULL;
816 }
817 }
818 }
819
820 ast_string_field_set(self, creator, creator);
821 if (!ast_strlen_zero(creator)) {
823 }
824 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init\n",
825 BRIDGE_PRINTF_VARS(self));
826
827 ast_set_flag(&self->feature_flags, flags);
828 self->allowed_capabilities = capabilities;
829
830 /* Use our helper function to find the "best" bridge technology. */
831 self->technology = find_best_technology(capabilities, self);
832 if (!self->technology) {
833 ast_log(LOG_WARNING, "Bridge %s: Could not create class %s. No technology to support it.\n",
834 self->uniqueid, self->v_table->name);
835 ao2_ref(self, -1);
836 return NULL;
837 }
838
839 /* Pass off the bridge to the technology to manipulate if needed */
840 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
841 self->uniqueid, self->technology->name);
842 if (self->technology->create && self->technology->create(self)) {
843 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
844 self->uniqueid, self->technology->name);
845 ao2_ref(self, -1);
846 return NULL;
847 }
848 ast_debug(1, "Bridge %s: calling %s technology start\n",
849 self->uniqueid, self->technology->name);
850 if (self->technology->start && self->technology->start(self)) {
851 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
852 self->uniqueid, self->technology->name);
853 ao2_ref(self, -1);
854 return NULL;
855 }
856
857 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
858 if (!ast_bridge_topic(self)) {
859 ao2_ref(self, -1);
860 return NULL;
861 }
862 }
863
864 self->creationtime = ast_tvnow();
865 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init complete\n",
866 BRIDGE_PRINTF_VARS(self));
867
868 return self;
869}
ast_mutex_t lock
Definition: app_sla.c:337
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:1009
static struct ast_bridge_technology * find_best_technology(uint32_t capabilities, struct ast_bridge *bridge)
Helper function used to find the "best" bridge technology given specified capabilities.
Definition: bridge.c:518
static ast_mutex_t bridge_init_lock
Definition: bridge.c:136
#define BRIDGE_PRINTF_VARS(bridge)
Definition: bridge.h:80
#define BRIDGE_PRINTF_SPEC
Definition: bridge.h:79
@ AST_BRIDGE_FLAG_INVISIBLE
static const char name[]
Definition: format_mp3.c:68
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:593
int ast_bridge_topic_exists(const char *uniqueid)
Check if a stasis topic exists for a bridge uniqueid.
int bridge_topics_init(struct ast_bridge *bridge)
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
int(* start)(struct ast_bridge *bridge)
Request a bridge technology instance start operations.
int(* create)(struct ast_bridge *bridge)
Create a bridge technology instance for a bridge.
struct timeval creationtime
Definition: bridge.h:412
const ast_string_field uniqueid
Definition: bridge.h:405
struct ast_bridge_technology * technology
Definition: bridge.h:359
struct ast_flags feature_flags
Definition: bridge.h:373
uint32_t allowed_capabilities
Definition: bridge.h:375
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141

References ast_bridge::allowed_capabilities, ao2_ref, ast_bridge_destroy(), AST_BRIDGE_FLAG_INVISIBLE, ast_bridge_topic(), ast_bridge_topic_exists(), ast_debug, ast_log, ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), ast_uuid_generate_str(), AST_UUID_STR_LEN, bridge_init_lock, BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, bridge_topics_init(), ast_bridge_technology::create, ast_bridge::creationtime, ast_bridge::creator, ast_bridge::feature_flags, find_best_technology(), lock, LOG_WARNING, name, ast_bridge_methods::name, ast_bridge_technology::name, NULL, SCOPED_MUTEX, ast_bridge_technology::start, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by ast_bridge_base_new(), ast_bridge_basic_new(), bridge_agent_hold_new(), bridge_parking_new(), and bridge_stasis_new().

◆ bridge_dissolve()

void bridge_dissolve ( struct ast_bridge bridge,
int  cause 
)

Definition at line 326 of file bridge.c.

327{
328 struct ast_bridge_channel *bridge_channel;
329 struct ast_frame action = {
332 };
333
334 if (bridge->dissolved) {
335 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": already dissolved\n",
336 BRIDGE_PRINTF_VARS(bridge));
337 return;
338 }
339 bridge->dissolved = 1;
340
341 if (cause <= 0) {
343 }
344 bridge->cause = cause;
345
346 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": dissolving with cause %d(%s)\n",
347 BRIDGE_PRINTF_VARS(bridge), cause, ast_cause2str(cause));
348
349 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
350 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": kicking channel %s\n",
351 BRIDGE_PRINTF_VARS(bridge),
352 ast_channel_name(bridge_channel->chan));
353 ast_bridge_channel_leave_bridge(bridge_channel,
355 }
356
357 /* Must defer dissolving bridge because it is already locked. */
358 ast_bridge_queue_action(bridge, &action);
359 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": DEFERRED_DISSOLVING queued. current refcound: %d\n",
360 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
361
362}
int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action)
Put an action onto the specified bridge.
Definition: bridge.c:314
@ BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE
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_ACTION_DEFERRED_DISSOLVING
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
@ AST_FRAME_BRIDGE_ACTION
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
Structure that contains information regarding a channel in a bridge.
struct ast_channel * chan
struct ast_bridge_channels_list channels
Definition: bridge.h:367
unsigned int dissolved
Definition: bridge.h:394
int cause
Definition: bridge.h:390
Data structure associated with a single frame of data.
enum ast_frame_type frametype

References ao2_ref, ast_bridge_channel_leave_bridge(), ast_bridge_queue_action(), ast_cause2str(), AST_CAUSE_NORMAL_CLEARING, ast_channel_name(), ast_debug, AST_FRAME_BRIDGE_ACTION, AST_LIST_TRAVERSE, BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, ast_bridge::cause, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge::dissolved, and ast_frame::frametype.

Referenced by ast_bridge_destroy(), bridge_channel_dissolve_check(), bridge_dissolve_check_stolen(), and bridge_reconfigured().

◆ bridge_do_merge()

void bridge_do_merge ( struct ast_bridge dst_bridge,
struct ast_bridge src_bridge,
struct ast_bridge_channel **  kick_me,
unsigned int  num_kick,
unsigned int  optimized 
)

Definition at line 2117 of file bridge.c.

2119{
2120 struct ast_bridge_channel *bridge_channel;
2121 unsigned int idx;
2122
2123 ast_debug(1, "Merging bridge %s into bridge %s\n",
2124 src_bridge->uniqueid, dst_bridge->uniqueid);
2125
2126 ast_bridge_publish_merge(dst_bridge, src_bridge);
2127
2128 /*
2129 * Move channels from src_bridge over to dst_bridge.
2130 *
2131 * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
2132 * bridge_channel_internal_pull() alters the list we are traversing.
2133 */
2134 AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
2135 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2136 /*
2137 * The channel is already leaving let it leave normally because
2138 * pulling it may delete hooks that should run for this channel.
2139 */
2140 continue;
2141 }
2142 if (ast_test_flag(&bridge_channel->features->feature_flags,
2144 continue;
2145 }
2146
2147 if (kick_me) {
2148 for (idx = 0; idx < num_kick; ++idx) {
2149 if (bridge_channel == kick_me[idx]) {
2150 ast_bridge_channel_leave_bridge(bridge_channel,
2152 break;
2153 }
2154 }
2155 }
2156 bridge_channel_internal_pull(bridge_channel);
2157 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2158 /*
2159 * The channel died as a result of being pulled or it was
2160 * kicked. Leave it pointing to the original bridge.
2161 */
2162 continue;
2163 }
2164
2165 bridge_channel_moving(bridge_channel, bridge_channel->bridge, dst_bridge);
2166
2167 /* Point to new bridge.*/
2168 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2169
2170 if (bridge_channel_internal_push(bridge_channel)) {
2171 ast_bridge_features_remove(bridge_channel->features,
2173 ast_bridge_channel_leave_bridge(bridge_channel,
2175 }
2176 }
2178
2179 if (kick_me) {
2180 /*
2181 * Now we can kick any channels in the dst_bridge without
2182 * potentially dissolving the bridge.
2183 */
2184 for (idx = 0; idx < num_kick; ++idx) {
2185 bridge_channel = kick_me[idx];
2186 ast_bridge_channel_lock(bridge_channel);
2187 if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2190 bridge_channel_internal_pull(bridge_channel);
2191 }
2192 ast_bridge_channel_unlock(bridge_channel);
2193 }
2194 }
2195
2196 bridge_reconfigured(dst_bridge, !optimized);
2197 bridge_reconfigured(src_bridge, !optimized);
2198
2199 ast_debug(1, "Merged bridge %s into bridge %s\n",
2200 src_bridge->uniqueid, dst_bridge->uniqueid);
2201}
void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags)
Remove marked bridge channel feature hooks.
Definition: bridge.c:3570
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1472
static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
Definition: bridge.c:2076
static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
Definition: bridge.c:2091
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
@ BRIDGE_CHANNEL_STATE_WAIT
int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
@ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
Publish a bridge merge.
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_channel::@193 entry
struct ast_bridge_features * features
enum bridge_channel_state state
struct ast_flags feature_flags
#define ast_test_flag(p, flag)
Definition: utils.h:63

References AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, ast_bridge_channel_leave_bridge(), ast_bridge_channel_leave_bridge_nolock(), ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_bridge_publish_merge(), AST_CAUSE_NORMAL_CLEARING, ast_debug, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_test_flag, ast_bridge_channel::bridge, bridge_channel_change_bridge(), bridge_channel_internal_pull(), bridge_channel_internal_push(), bridge_channel_moving(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_reconfigured(), ast_bridge::cause, ast_bridge::channels, ast_bridge_channel::entry, ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge_channel::state, and ast_bridge::uniqueid.

Referenced by bridge_merge(), bridge_merge_locked(), try_merge_optimize_out(), and two_bridge_attended_transfer().

◆ bridge_do_move()

int bridge_do_move ( struct ast_bridge dst_bridge,
struct ast_bridge_channel bridge_channel,
int  attempt_recovery,
unsigned int  optimized 
)

Definition at line 2383 of file bridge.c.

2385{
2386 struct ast_bridge *orig_bridge;
2387 int was_in_bridge;
2388 int res = 0;
2389
2390 if (bridge_channel->swap) {
2391 ast_debug(1, "Moving %p(%s) into bridge %s swapping with %s\n",
2392 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid,
2393 ast_channel_name(bridge_channel->swap));
2394 } else {
2395 ast_debug(1, "Moving %p(%s) into bridge %s\n",
2396 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid);
2397 }
2398
2399 orig_bridge = bridge_channel->bridge;
2400 was_in_bridge = bridge_channel->in_bridge;
2401
2402 bridge_channel_internal_pull(bridge_channel);
2403 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2404 /*
2405 * The channel died as a result of being pulled. Leave it
2406 * pointing to the original bridge.
2407 *
2408 * Clear out the swap channel pointer. A ref is not held
2409 * by bridge_channel->swap at this point.
2410 */
2411 bridge_channel->swap = NULL;
2412 bridge_reconfigured(orig_bridge, 0);
2413 return -1;
2414 }
2415
2416 /* Point to new bridge.*/
2417 ao2_ref(orig_bridge, +1);/* Keep a ref in case the push fails. */
2418 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2419
2420 bridge_channel_moving(bridge_channel, orig_bridge, dst_bridge);
2421
2422 if (bridge_channel_internal_push_full(bridge_channel, optimized)) {
2423 /* Try to put the channel back into the original bridge. */
2424 ast_bridge_features_remove(bridge_channel->features,
2426 if (attempt_recovery && was_in_bridge) {
2427 /* Point back to original bridge. */
2428 bridge_channel_change_bridge(bridge_channel, orig_bridge);
2429
2430 if (bridge_channel_internal_push(bridge_channel)) {
2431 ast_bridge_features_remove(bridge_channel->features,
2433 ast_bridge_channel_leave_bridge(bridge_channel,
2435 }
2436 } else {
2437 ast_bridge_channel_leave_bridge(bridge_channel,
2439 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2440 }
2441 res = -1;
2442 } else if (!optimized) {
2443 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2444 }
2445
2446 bridge_reconfigured(dst_bridge, !optimized);
2447 bridge_reconfigured(orig_bridge, !optimized);
2448 ao2_ref(orig_bridge, -1);
2449 return res;
2450}
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_push_full(struct ast_bridge_channel *bridge_channel, int optimized)
struct ast_channel * swap
unsigned int in_bridge

References ao2_ref, ast_bridge_channel_leave_bridge(), ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_channel_name(), ast_debug, ast_bridge_channel::bridge, bridge_channel_change_bridge(), bridge_channel_internal_pull(), bridge_channel_internal_push(), bridge_channel_internal_push_full(), bridge_channel_moving(), bridge_channel_settle_owed_events(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_reconfigured(), ast_bridge::cause, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_channel::in_bridge, NULL, ast_bridge_channel::state, ast_bridge_channel::swap, and ast_bridge::uniqueid.

Referenced by bridge_move(), bridge_move_locked(), bridge_swap_attended_transfer(), and try_swap_optimize_out().

◆ bridge_find_channel()

struct ast_bridge_channel * bridge_find_channel ( struct ast_bridge bridge,
struct ast_channel chan 
)

◆ bridge_merge_inhibit_nolock()

void bridge_merge_inhibit_nolock ( struct ast_bridge bridge,
int  request 
)

Definition at line 3060 of file bridge.c.

3061{
3062 int new_request;
3063
3064 new_request = bridge->inhibit_merge + request;
3065 ast_assert(0 <= new_request);
3066 bridge->inhibit_merge = new_request;
3067}
static int request(void *obj)
Definition: chan_pjsip.c:2605
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed.
Definition: bridge.h:388

References ast_assert, ast_bridge::inhibit_merge, and request().

Referenced by ast_bridge_channel_merge_inhibit(), and ast_bridge_merge_inhibit().

◆ bridge_reconfigured()

void bridge_reconfigured ( struct ast_bridge bridge,
unsigned int  colp_update 
)

Definition at line 1472 of file bridge.c.

1473{
1474 if (!bridge->reconfigured) {
1475 return;
1476 }
1477 bridge->reconfigured = 0;
1479 && smart_bridge_operation(bridge)) {
1480 /* Smart bridge failed. */
1481 bridge_dissolve(bridge, 0);
1482 return;
1483 }
1484 bridge_complete_join(bridge);
1485
1486 if (bridge->dissolved) {
1487 return;
1488 }
1490 set_bridge_peer_vars(bridge);
1492
1493 if (colp_update) {
1495 }
1496}
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:326
static void check_bridge_play_sounds(struct ast_bridge *bridge)
Definition: bridge.c:1272
static int smart_bridge_operation(struct ast_bridge *bridge)
Definition: bridge.c:1041
static void bridge_reconfigured_connected_line_update(struct ast_bridge *bridge)
Definition: bridge.c:404
static void bridge_complete_join(struct ast_bridge *bridge)
Definition: bridge.c:493
static void set_bridge_peer_vars(struct ast_bridge *bridge)
Definition: bridge.c:1455
@ AST_BRIDGE_FLAG_SMART
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
unsigned int reconfigured
Definition: bridge.h:392

References AST_BRIDGE_FLAG_SMART, ast_bridge_publish_state(), ast_test_flag, ast_bridge_channel::bridge, bridge_complete_join(), bridge_dissolve(), bridge_reconfigured_connected_line_update(), check_bridge_play_sounds(), ast_bridge::dissolved, ast_bridge::feature_flags, ast_bridge::reconfigured, set_bridge_peer_vars(), and smart_bridge_operation().

Referenced by ast_bridge_notify_masquerade(), bridge_channel_handle_control(), bridge_channel_internal_join(), bridge_channel_wait(), bridge_do_merge(), and bridge_do_move().

◆ bridge_register()

struct ast_bridge * bridge_register ( struct ast_bridge bridge)

Register the new bridge with the system.

Since
12.0.0
Parameters
bridgeWhat to register. (Tolerates a NULL pointer)
struct ast_bridge *ast_bridge_basic_new(uint32_t capabilities, int flags, uint32 dtmf_features)
{
void *bridge;
bridge = bridge_alloc(sizeof(struct ast_bridge_basic), &ast_bridge_basic_v_table);
bridge = bridge_base_init(bridge, capabilities, flags);
bridge = ast_bridge_basic_init(bridge, dtmf_features);
bridge = bridge_register(bridge);
return bridge;
}
struct ast_bridge_methods ast_bridge_basic_v_table
Bridge basic class virtual method table.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:713
Note
This must be done after a bridge constructor has completed setting up the new bridge but before it returns.
After a bridge is registered, ast_bridge_destroy() must eventually be called to get rid of the bridge.
Returns
bridge on success.
Return values
NULLon error.

Definition at line 713 of file bridge.c.

714{
715 if (bridge) {
717 /*
718 * Although bridge_base_init() should have already checked for
719 * an existing bridge with the same uniqueid, bridge_base_init()
720 * and bridge_register() are two separate public APIs so we need
721 * to check again here.
722 */
723 struct ast_bridge *existing = ast_bridge_find_by_id(bridge->uniqueid);
724 if (existing) {
725 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
726 BRIDGE_PRINTF_VARS(bridge));
727 ao2_ref(existing, -1);
728 ast_bridge_destroy(bridge, 0);
729 return NULL;
730 }
731 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": registering\n",
732 BRIDGE_PRINTF_VARS(bridge));
733 bridge->construction_completed = 1;
734 ast_bridge_lock(bridge);
736 ast_bridge_unlock(bridge);
737 if (!ao2_link(bridges, bridge)) {
738 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": failed to link\n",
739 BRIDGE_PRINTF_VARS(bridge));
740 ast_bridge_destroy(bridge, 0);
741 bridge = NULL;
742 }
743 }
744 return bridge;
745}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5081
static struct ao2_container * bridges
Definition: bridge.c:132
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:485
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:474
unsigned int construction_completed
Definition: bridge.h:396

References ao2_link, ao2_ref, ast_bridge_destroy(), ast_bridge_find_by_id(), ast_bridge_lock, ast_bridge_publish_state(), ast_bridge_unlock, ast_debug, ast_log, bridge_init_lock, BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, bridges, ast_bridge::construction_completed, lock, LOG_WARNING, NULL, SCOPED_MUTEX, and ast_bridge::uniqueid.

Referenced by ast_bridge_base_new(), ast_bridge_basic_new(), bridge_agent_hold_new(), bridge_parking_new(), and bridge_stasis_new().