mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
res_pjsip_rfc3326: Add SIP causes support for RFC3326
Add ability to set HANGUPCAUSE when SIP causecode received in BYE (in addition to currently supported Q.850). ASTERISK-30319 #close Change-Id: I3f55622dc680ce713a2ffb5a458ef5dd39fcf645
This commit is contained in:
committed by
George Joseph
parent
4710f37ef6
commit
3526441e41
@@ -40,6 +40,7 @@
|
||||
#include "asterisk/uuid.h"
|
||||
#include "asterisk/sorcery.h"
|
||||
#include "asterisk/file.h"
|
||||
#include "asterisk/causes.h"
|
||||
#include "asterisk/cli.h"
|
||||
#include "asterisk/callerid.h"
|
||||
#include "asterisk/res_pjsip_cli.h"
|
||||
@@ -2796,6 +2797,97 @@ struct pjsip_param *ast_sip_pjsip_uri_get_other_param(pjsip_uri *uri, const pj_s
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! \brief Convert SIP hangup causes to Asterisk hangup causes */
|
||||
const int ast_sip_hangup_sip2cause(int cause)
|
||||
{
|
||||
/* Possible values taken from causes.h */
|
||||
|
||||
switch(cause) {
|
||||
case 401: /* Unauthorized */
|
||||
return AST_CAUSE_CALL_REJECTED;
|
||||
case 403: /* Not found */
|
||||
return AST_CAUSE_CALL_REJECTED;
|
||||
case 404: /* Not found */
|
||||
return AST_CAUSE_UNALLOCATED;
|
||||
case 405: /* Method not allowed */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 407: /* Proxy authentication required */
|
||||
return AST_CAUSE_CALL_REJECTED;
|
||||
case 408: /* No reaction */
|
||||
return AST_CAUSE_NO_USER_RESPONSE;
|
||||
case 409: /* Conflict */
|
||||
return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
|
||||
case 410: /* Gone */
|
||||
return AST_CAUSE_NUMBER_CHANGED;
|
||||
case 411: /* Length required */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 413: /* Request entity too large */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 414: /* Request URI too large */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 415: /* Unsupported media type */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 420: /* Bad extension */
|
||||
return AST_CAUSE_NO_ROUTE_DESTINATION;
|
||||
case 480: /* No answer */
|
||||
return AST_CAUSE_NO_ANSWER;
|
||||
case 481: /* No answer */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 482: /* Loop detected */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 483: /* Too many hops */
|
||||
return AST_CAUSE_NO_ANSWER;
|
||||
case 484: /* Address incomplete */
|
||||
return AST_CAUSE_INVALID_NUMBER_FORMAT;
|
||||
case 485: /* Ambiguous */
|
||||
return AST_CAUSE_UNALLOCATED;
|
||||
case 486: /* Busy everywhere */
|
||||
return AST_CAUSE_BUSY;
|
||||
case 487: /* Request terminated */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 488: /* No codecs approved */
|
||||
return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
|
||||
case 491: /* Request pending */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 493: /* Undecipherable */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 500: /* Server internal failure */
|
||||
return AST_CAUSE_FAILURE;
|
||||
case 501: /* Call rejected */
|
||||
return AST_CAUSE_FACILITY_REJECTED;
|
||||
case 502:
|
||||
return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
case 503: /* Service unavailable */
|
||||
return AST_CAUSE_CONGESTION;
|
||||
case 504: /* Gateway timeout */
|
||||
return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
|
||||
case 505: /* SIP version not supported */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
case 600: /* Busy everywhere */
|
||||
return AST_CAUSE_USER_BUSY;
|
||||
case 603: /* Decline */
|
||||
return AST_CAUSE_CALL_REJECTED;
|
||||
case 604: /* Does not exist anywhere */
|
||||
return AST_CAUSE_UNALLOCATED;
|
||||
case 606: /* Not acceptable */
|
||||
return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
|
||||
default:
|
||||
if (cause < 500 && cause >= 400) {
|
||||
/* 4xx class error that is unknown - someting wrong with our request */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
} else if (cause < 600 && cause >= 500) {
|
||||
/* 5xx class error - problem in the remote end */
|
||||
return AST_CAUSE_CONGESTION;
|
||||
} else if (cause < 700 && cause >= 600) {
|
||||
/* 6xx - global errors in the 4xx class */
|
||||
return AST_CAUSE_INTERWORKING;
|
||||
}
|
||||
return AST_CAUSE_NORMAL;
|
||||
}
|
||||
/* Never reached */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TEST_FRAMEWORK
|
||||
AST_TEST_DEFINE(xml_sanitization_end_null)
|
||||
{
|
||||
|
@@ -42,6 +42,7 @@ static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pj
|
||||
char *cause;
|
||||
char *text;
|
||||
int code;
|
||||
int cause_q850, cause_sip;
|
||||
|
||||
header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_reason, NULL);
|
||||
for (; header;
|
||||
@@ -49,21 +50,27 @@ static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pj
|
||||
ast_copy_pj_str(buf, &header->hvalue, sizeof(buf));
|
||||
cause = ast_skip_blanks(buf);
|
||||
|
||||
if (strncasecmp(cause, "Q.850", 5) || !(cause = strstr(cause, "cause="))) {
|
||||
cause_q850 = !strncasecmp(cause, "Q.850", 5);
|
||||
cause_sip = !strncasecmp(cause, "SIP", 3);
|
||||
if ((cause_q850 || cause_sip) && (cause = strstr(cause, "cause="))) {
|
||||
/* If text is present get rid of it */
|
||||
if ((text = strchr(cause, ';'))) {
|
||||
*text = '\0';
|
||||
}
|
||||
|
||||
if (sscanf(cause, "cause=%30d", &code) != 1) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If text is present get rid of it */
|
||||
if ((text = strstr(cause, ";"))) {
|
||||
*text = '\0';
|
||||
if (cause_q850) {
|
||||
ast_channel_hangupcause_set(session->channel, code & 0x7f);
|
||||
break;
|
||||
} else if (cause_sip) {
|
||||
ast_channel_hangupcause_set(session->channel, ast_sip_hangup_sip2cause(code));
|
||||
break;
|
||||
}
|
||||
|
||||
if (sscanf(cause, "cause=%30d", &code) != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_channel_hangupcause_set(session->channel, code & 0x7f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user