/*! * \internal * \brief Send the peer channel on its way on bridge start failure. * \since 12.0.0 * * \param chan Chan to put into autoservice. * \param peer Chan to send to after bridge goto or run hangup handlers and hangup. * * \return Nothing */ static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer) { if (ast_bridge_setup_after_goto(peer) || ast_pbx_start(peer)) { ast_autoservice_chan_hangup_peer(chan, peer); } }
static void internal_bridge_after_cb(struct ast_channel *chan, void *data, enum ast_bridge_after_cb_reason reason) { struct stasis_app_control *control = data; SCOPED_AO2LOCK(lock, control); struct ast_bridge_channel *bridge_channel; ast_debug(3, "%s, %s: %s\n", ast_channel_uniqueid(chan), control->bridge ? control->bridge->uniqueid : "unknown", ast_bridge_after_cb_reason_string(reason)); if (reason == AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED) { /* The impart actually failed so control->bridge isn't valid. */ control->bridge = NULL; } ast_assert(chan == control->channel); /* Restore the channel's PBX */ ast_channel_pbx_set(control->channel, control->pbx); control->pbx = NULL; if (control->bridge) { app_unsubscribe_bridge(control->app, control->bridge); /* No longer in the bridge */ control->bridge = NULL; /* Get the bridge channel so we don't depart from the wrong bridge */ ast_channel_lock(chan); bridge_channel = ast_channel_get_bridge_channel(chan); ast_channel_unlock(chan); /* Depart this channel from the bridge using the command queue if possible */ stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel, __ao2_cleanup); } if (stasis_app_channel_is_stasis_end_published(chan)) { /* The channel has had a StasisEnd published on it, but until now had remained in * the bridging system. This means that the channel moved from a Stasis bridge to a * non-Stasis bridge and is now exiting the bridging system. Because of this, the * channel needs to exit the Stasis application and go to wherever the non-Stasis * bridge has directed it to go. If the non-Stasis bridge has not set up an after * bridge destination, then the channel should be hung up. */ int hangup_flag; hangup_flag = ast_bridge_setup_after_goto(chan) ? AST_SOFTHANGUP_DEV : AST_SOFTHANGUP_ASYNCGOTO; ast_channel_lock(chan); ast_softhangup_nolock(chan, hangup_flag); ast_channel_unlock(chan); } }