if (!res) {
ast_channel_lock(autochan->chan);
if (ast_channel_is_bridged(autochan->chan)) {
- ast_softhangup_nolock(autochan->chan, AST_SOFTHANGUP_UNBRIDGE);
+ ast_channel_set_unbridged_nolock(autochan->chan, 1);
}
ast_channel_unlock(autochan->chan);
}
if (!res) {
ast_channel_lock(chan);
if (ast_channel_is_bridged(chan)) {
- ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+ ast_channel_set_unbridged_nolock(chan, 1);
}
ast_channel_unlock(chan);
}
/* Save non-hangup softhangup flags. */
saved_hangup_flags = ast_channel_softhangup_internal_flag(chan)
- & (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+ & AST_SOFTHANGUP_ASYNCGOTO;
if (saved_hangup_flags) {
- ast_channel_clear_softhangup(chan,
- AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+ ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ASYNCGOTO);
}
/* Save autoloop flag */
*/
do {
/* Check for hangup. */
- if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE) {
- saved_hangup_flags |= AST_SOFTHANGUP_UNBRIDGE;
- ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_UNBRIDGE);
- }
if (ast_check_hangup(chan)) {
if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
ast_log(LOG_ERROR, "%s An async goto just messed up our execution location.\n",
* needed.
*/
AST_SOFTHANGUP_EXPLICIT = (1 << 5),
- /*!
- * Used to request that the bridge core re-evaluate the current
- * bridging technology in use by the bridge this channel is in.
- */
- AST_SOFTHANGUP_UNBRIDGE = (1 << 6),
/*!
* Used to indicate that the channel is currently executing hangup
* logic in the dialplan. The channel has been hungup when this is
int ast_check_hangup_locked(struct ast_channel *chan);
+/*! \brief This function will check if the bridge needs to be re-evaluated due to
+ * external changes.
+ *
+ * \param chan Channel on which to check the unbridge_eval flag
+ *
+ * \return Returns 0 if the flag is down or 1 if the flag is up.
+ */
+int ast_channel_unbridged(struct ast_channel *chan);
+
+/*! \brief ast_channel_unbridged variant. Use this if the channel
+ * is already locked prior to calling.
+ *
+ * \param chan Channel on which to check the unbridge flag
+ *
+ * \return Returns 0 if the flag is down or 1 if the flag is up.
+ */
+int ast_channel_unbridged_nolock(struct ast_channel *chan);
+
+/*! \brief Sets the unbridged flag and queues a NULL frame on the channel to trigger
+ * a check by bridge_channel_wait
+ *
+ * \param chan Which channel is having its unbridged value set
+ * \param value What the unbridge value is being set to
+ */
+void ast_channel_set_unbridged(struct ast_channel *chan, int value);
+
+/*! \brief Variant of ast_channel_set_unbridged. Use this if the channel
+ * is already locked prior to calling.
+ *
+ * \param chan Which channel is having its unbridged value set
+ * \param value What the unbridge value is being set to
+ */
+void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value);
+
/*!
* \brief Lock the given channel, then request softhangup on the channel with the given causecode
* \param chan channel on which to hang up
int goto_failed = -1;
/* We are going to be leaving the bridging system now;
- * clear any pending UNBRIDGE flags
+ * clear any pending unbridge flags
*/
- ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_UNBRIDGE);
+ ast_channel_set_unbridged(chan, 0);
/* Determine if we are going to setup a dialplan location and where. */
if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
ms = bridge_channel_next_interval(bridge_channel);
chan = ast_waitfor_nandfds(&bridge_channel->chan, 1,
&bridge_channel->alert_pipe[0], 1, NULL, &outfd, &ms);
- if (ast_channel_softhangup_internal_flag(bridge_channel->chan) & AST_SOFTHANGUP_UNBRIDGE) {
- ast_channel_clear_softhangup(bridge_channel->chan, AST_SOFTHANGUP_UNBRIDGE);
+ if (ast_channel_unbridged(bridge_channel->chan)) {
+ ast_channel_set_unbridged(bridge_channel->chan, 0);
ast_bridge_channel_lock_bridge(bridge_channel);
bridge_channel->bridge->reconfigured = 1;
bridge_reconfigured(bridge_channel->bridge, 0);
int ast_channel_is_leaving_bridge(struct ast_channel *chan)
{
int hangup_flags = ast_channel_softhangup_internal_flag(chan);
- int hangup_test = hangup_flags & (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+ int hangup_test = hangup_flags & AST_SOFTHANGUP_ASYNCGOTO;
- /* This function should only return true if either ASYNCGOTO
- * or UNBRIDGE is set, or both flags are set. It should return
- * false if any other flag is set.
+ /* This function should only return true if only the ASYNCGOTO
+ * is set. It should false if any other flag is set or if the
+ * ASYNCGOTO flag is not set.
*/
return (hangup_test && (hangup_test == hangup_flags));
}
ast_channel_lock(chan);
dead = ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)
|| (ast_channel_softhangup_internal_flag(chan)
- & ~(AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE));
+ & ~AST_SOFTHANGUP_ASYNCGOTO);
ast_channel_unlock(chan);
if (dead) {
/* Channel is a zombie or a real hangup. */
* See \arg \ref AstFileDesc */
int softhangup; /*!< Whether or not we have been hung up... Do not set this value
* directly, use ast_softhangup() */
+ int unbridged; /*!< If non-zero, the bridge core needs to re-evaluate the current
+ bridging technology which is in use by this channel's bridge. */
int fdno; /*!< Which fd had an event detected on */
int streamid; /*!< For streaming playback, the schedule ID */
int vstreamid; /*!< For streaming video playback, the schedule ID */
ast_data_add_bool(data_softhangup, "timeout", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_TIMEOUT);
ast_data_add_bool(data_softhangup, "appunload", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_APPUNLOAD);
ast_data_add_bool(data_softhangup, "explicit", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_EXPLICIT);
- ast_data_add_bool(data_softhangup, "unbridge", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE);
/* channel flags */
data_flags = ast_data_add_node(tree, "flags");
chan ->softhangup &= ~value;
}
+int ast_channel_unbridged_nolock(struct ast_channel *chan)
+{
+ return chan->unbridged;
+}
+
+int ast_channel_unbridged(struct ast_channel *chan)
+{
+ int res;
+ ast_channel_lock(chan);
+ res = ast_channel_unbridged_nolock(chan);
+ ast_channel_unlock(chan);
+ return res;
+}
+
+void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
+{
+ chan->unbridged = value;
+ ast_queue_frame(chan, &ast_null_frame);
+}
+
+void ast_channel_set_unbridged(struct ast_channel *chan, int value)
+{
+ ast_channel_lock(chan);
+ ast_channel_set_unbridged_nolock(chan, value);
+ ast_channel_unlock(chan);
+}
+
void ast_channel_callid_cleanup(struct ast_channel *chan)
{
if (chan->callid) {
}
if (ast_channel_is_bridged(chan)) {
- ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+ ast_channel_set_unbridged_nolock(chan, 1);
}
return framehook->id;
AST_LIST_TRAVERSE_SAFE_END;
if (ast_channel_is_bridged(chan)) {
- ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+ ast_channel_set_unbridged_nolock(chan, 1);
}
return res;
S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL),
&found, 1))) {
- /* Defensively clear the UNBRIDGE flag in case it leaked
- * out of the bridging framework. UNBRIDE never implies
- * that a channel is hung up.
- */
- ast_channel_clear_softhangup(c, AST_SOFTHANGUP_UNBRIDGE);
if (!ast_check_hangup(c)) {
ast_channel_priority_set(c, ast_channel_priority(c) + 1);
continue;