[Asterisk-Dev] IAX2 Frame_Text to send Hangup Cause
Tilghman Lesher
tilghman at mail.jeffandtilghman.com
Fri Dec 10 11:13:41 MST 2004
On Friday 10 December 2004 11:22, reseaux wrote:
> i know is not a solution but is a great Hack!! With my little Remove of
> the two line in Chan_iax2.c i can give any problem? Can you give me some
> idea how to replace this two line in Chan_iax2.c for example:
> --------------------
> /* Set hangup cause */
> if AST_FRAME_TEXT != "hangupcause=" {
> if (ies.cause)
> iaxs[fr.callno]->owner->hangupcause = atoi(ies.cause);
> }
> ---------------------
> Is not C code line :-) but i use to explain how want fix it.
Attached is a better way to do it, given some time to look at the code
and find the right way to send messages. What I've done is to create a
Q.931 code to be sent along with a IAX_COMMAND_HANGUP frame and
receive that code on the remote end, to be inserted into the channel
hangupcause at the appropriate time.
BTW, this is a patch against CVS, so I have no idea if it will cleanly apply
against one of the releases.
--
Tilghman
-------------- next part --------------
Index: channels/chan_iax2.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v
retrieving revision 1.221
diff -u -r1.221 chan_iax2.c
--- channels/chan_iax2.c 29 Nov 2004 03:24:35 -0000 1.221
+++ channels/chan_iax2.c 10 Dec 2004 18:04:25 -0000
@@ -1489,6 +1489,7 @@
fr.frametype = AST_FRAME_CONTROL;
fr.subclass = AST_CONTROL_HANGUP;
iax2_queue_frame(f->callno, &fr);
+ iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
} else {
if (iaxs[f->callno]->reg) {
memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us));
@@ -4634,8 +4635,10 @@
memset(&ied, 0, sizeof(ied));
if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
+ iax_ie_append_int(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
} else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
+ iax_ie_append_int(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
}
send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
}
@@ -4671,6 +4674,7 @@
iaxs[callno]->autoid = -1;
memset(&ied, 0, sizeof(ied));
iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
+ iax_ie_append_int(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
}
ast_mutex_unlock(&iaxsl[callno]);
@@ -5460,6 +5465,7 @@
if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) {
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
if (authdebug)
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
@@ -5471,6 +5476,7 @@
if (!format) {
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
if (authdebug)
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability);
@@ -5480,6 +5486,7 @@
if (!format) {
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
if (authdebug)
@@ -5530,6 +5537,9 @@
case IAX_COMMAND_HANGUP:
iaxs[fr.callno]->alreadygone = 1;
ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno);
+ /* Set hangup cause according to remote */
+ if (ies.causecode)
+ iaxs[fr.callno]->owner->hangupcause = ies.causecode;
/* Send ack immediately, before we destroy */
send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
iax2_destroy_nolock(fr.callno);
@@ -5596,6 +5606,7 @@
if (!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) {
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
if (authdebug)
ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability);
@@ -5758,6 +5769,7 @@
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
} else {
/* Select an appropriate format */
@@ -5770,6 +5782,7 @@
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability);
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
} else {
/* Pick one... */
@@ -5780,6 +5793,7 @@
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability);
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
}
}
@@ -5815,6 +5829,7 @@
ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
} else {
iaxs[fr.callno]->state |= IAX_STATE_STARTED;
@@ -5884,6 +5899,7 @@
if (registry_rerequest(&ies, fr.callno, &sin)) {
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
+ iax_ie_append_int(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
}
break;
Index: channels/iax2-parser.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/iax2-parser.c,v
retrieving revision 1.30
diff -u -r1.30 iax2-parser.c
--- channels/iax2-parser.c 19 Nov 2004 21:52:25 -0000 1.30
+++ channels/iax2-parser.c 10 Dec 2004 18:04:25 -0000
@@ -632,6 +632,13 @@
case IAX_IE_CAUSE:
ies->cause = data + 2;
break;
+ case IAX_IE_CAUSECODE:
+ if (len != (int)sizeof(unsigned int)) {
+ snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+ errorf(tmp);
+ } else
+ ies->causecode = ntohl(*((unsigned int *)(data + 2)));
+ break;
case IAX_IE_IAX_UNKNOWN:
if (len == 1)
ies->iax_unknown = data[2];
Index: channels/iax2-parser.h
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/iax2-parser.h,v
retrieving revision 1.11
diff -u -r1.11 iax2-parser.h
--- channels/iax2-parser.h 19 Nov 2004 21:52:25 -0000 1.11
+++ channels/iax2-parser.h 10 Dec 2004 18:04:25 -0000
@@ -41,6 +41,7 @@
unsigned short dpstatus;
unsigned short callno;
char *cause;
+ unsigned int causecode;
unsigned char iax_unknown;
int msgcount;
int autoanswer;
Index: channels/iax2.h
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/iax2.h,v
retrieving revision 1.17
diff -u -r1.17 iax2.h
--- channels/iax2.h 19 Nov 2004 21:52:25 -0000 1.17
+++ channels/iax2.h 10 Dec 2004 18:04:25 -0000
@@ -116,6 +116,7 @@
#define IAX_IE_CALLINGTON 39 /* Calling type of number (u8) */
#define IAX_IE_CALLINGTNS 40 /* Calling transit network select (u16) */
#define IAX_IE_SAMPLINGRATE 41 /* Supported sampling rates (u16) */
+#define IAX_IE_CAUSECODE 42 /* Hangup cause - int */
#define IAX_AUTH_PLAINTEXT (1 << 0)
#define IAX_AUTH_MD5 (1 << 1)
More information about the asterisk-dev
mailing list