diff options
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_iax2.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 467cdb4e3..8f42bf385 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -10135,6 +10135,62 @@ static int socket_process(struct iax2_thread *thread) } #endif + if (iaxs[fr->callno]->owner && (fh->type == AST_FRAME_IAX || fh->type == AST_FRAME_CONTROL)) { + struct ast_control_pvt_cause_code *cause_code; + int data_size = sizeof(*cause_code); + char subclass[40] = ""; + + /* get subclass text */ + if (fh->type == AST_FRAME_IAX) { + iax_frame_subclass2str(fh->csub, subclass, sizeof(subclass)); + } else { + struct ast_frame tmp_frame = {0,}; + tmp_frame.frametype = fh->type; + tmp_frame.subclass.integer = fh->csub; + ast_frame_subclass2str(&tmp_frame, subclass, sizeof(subclass), NULL, 0); + } + + /* add length of "IAX2 " */ + data_size += 5; + if (fh->type == AST_FRAME_CONTROL) { + /* add length of "Control " */ + data_size += 8; + } else if (fh->csub == IAX_COMMAND_HANGUP + || fh->csub == IAX_COMMAND_REJECT + || fh->csub == IAX_COMMAND_REGREJ + || fh->csub == IAX_COMMAND_TXREJ) { + /* for IAX hangup frames, add length of () and number */ + data_size += 3; + if (ies.causecode > 9) { + data_size++; + } + if (ies.causecode > 99) { + data_size++; + } + } + /* add length of subclass */ + data_size += strlen(subclass); + + cause_code = alloca(data_size); + ast_copy_string(cause_code->chan_name, ast_channel_name(iaxs[fr->callno]->owner), AST_CHANNEL_NAME); + + if (fh->type == AST_FRAME_IAX && + (fh->csub == IAX_COMMAND_HANGUP + || fh->csub == IAX_COMMAND_REJECT + || fh->csub == IAX_COMMAND_REGREJ + || fh->csub == IAX_COMMAND_TXREJ)) { + snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "IAX2 %s(%d)", subclass, ies.causecode); + } else { + snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "IAX2 %s%s", (fh->type == AST_FRAME_CONTROL ? "Control " : ""), subclass); + } + + iax2_queue_control_data(fr->callno, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size); + if (!iaxs[fr->callno]) { + ast_variables_destroy(ies.vars); + ast_mutex_unlock(&iaxsl[fr->callno]); + return 1; + } + } /* count this frame */ iaxs[fr->callno]->frames_received++; |