Index: channels/chan_iax2.c =================================================================== --- channels/chan_iax2.c (revision 387927) +++ channels/chan_iax2.c (working copy) @@ -11509,64 +11509,83 @@ } break; case IAX_COMMAND_TXREJ: - iaxs[fr->callno]->transferring = 0; + iaxs[fr->callno]->transferring = TRANSFER_NONE; ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : ""); memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); if (iaxs[fr->callno]->bridgecallno) { if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { - iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; + iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE; send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); } } break; case IAX_COMMAND_TXREADY: - if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || - (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { - if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) - iaxs[fr->callno]->transferring = TRANSFER_MREADY; - else - iaxs[fr->callno]->transferring = TRANSFER_READY; - ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : ""); + if (iaxs[fr->callno]->bridgecallno) { + while (ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) { + DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); + } + if (!iaxs[fr->callno]) { + break; + } + } + + if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) { + iaxs[fr->callno]->transferring = TRANSFER_MREADY; + } else if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { + iaxs[fr->callno]->transferring = TRANSFER_READY; + } else { if (iaxs[fr->callno]->bridgecallno) { - if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || - (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { - /* They're both ready, now release them. */ - if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { - ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "", - iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : ""); + ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); + } + break; + } - iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; - iaxs[fr->callno]->transferring = TRANSFER_MEDIA; + ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : ""); - memset(&ied0, 0, sizeof(ied0)); - memset(&ied1, 0, sizeof(ied1)); - iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); - iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); - send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); - send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); - } else { - ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "", - iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : ""); + if (iaxs[fr->callno]->bridgecallno) { + if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY) { + /* They're both ready, now release them. */ + ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "", + iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : ""); - iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; - iaxs[fr->callno]->transferring = TRANSFER_RELEASED; - ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); - ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); + iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; + iaxs[fr->callno]->transferring = TRANSFER_MEDIA; - /* Stop doing lag & ping requests */ - stop_stuff(fr->callno); - stop_stuff(iaxs[fr->callno]->bridgecallno); + memset(&ied0, 0, sizeof(ied0)); + memset(&ied1, 0, sizeof(ied1)); - memset(&ied0, 0, sizeof(ied0)); - memset(&ied1, 0, sizeof(ied1)); - iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); - iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); - send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); - send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); - } + iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); + iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); - } + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); + send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); + + } else if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) { + /* They're both ready, now release them. */ + ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "", + iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : ""); + + iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; + iaxs[fr->callno]->transferring = TRANSFER_RELEASED; + + ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); + ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); + + /* Stop doing lag & ping requests */ + stop_stuff(fr->callno); + stop_stuff(iaxs[fr->callno]->bridgecallno); + + memset(&ied0, 0, sizeof(ied0)); + memset(&ied1, 0, sizeof(ied1)); + + iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); + iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); + + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); + send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); + } + ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); } break; case IAX_COMMAND_TXREQ: