diff options
Diffstat (limited to 'main/bridge.c')
-rw-r--r-- | main/bridge.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/main/bridge.c b/main/bridge.c index 9d8d807f8..fd83cfb7b 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -4036,19 +4036,25 @@ static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *cha BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2); if (bridge2) { - RAII_VAR(struct ast_channel *, local_chan2, NULL, ao2_cleanup); struct ast_channel *locals[2]; - ast_channel_lock(local_chan); - local_chan2 = ast_local_get_peer(local_chan); - ast_channel_unlock(local_chan); - - ast_assert(local_chan2 != NULL); + /* Have to lock everything just in case a hangup comes in early */ + ast_local_lock_all(local_chan, &locals[0], &locals[1]); + if (!locals[0] || !locals[1]) { + ast_log(LOG_ERROR, "Transfer failed probably due to an early hangup - " + "missing other half of '%s'\n", ast_channel_name(local_chan)); + ast_local_unlock_all(local_chan); + ao2_cleanup(local_chan); + return AST_BRIDGE_TRANSFER_FAIL; + } - locals[0] = local_chan; - locals[1] = local_chan2; + /* Make sure the peer is properly set */ + if (local_chan != locals[0]) { + SWAP(locals[0], locals[1]); + } ast_attended_transfer_message_add_link(transfer_msg, locals); + ast_local_unlock_all(local_chan); } else { ast_attended_transfer_message_add_app(transfer_msg, app, local_chan); } |