diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 0a19b3cb19..2c824f1641 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1864,18 +1864,31 @@ static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_r /*--- hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---*/ static int hangup_sip2cause(int cause) { -/* Possible values from causes.h - AST_CAUSE_NOTDEFINED AST_CAUSE_NORMAL AST_CAUSE_BUSY - AST_CAUSE_FAILURE AST_CAUSE_CONGESTION AST_CAUSE_UNALLOCATED -*/ +/* Possible values taken from causes.h */ switch(cause) { + case 403: /* Not found */ + return AST_CAUSE_CALL_REJECTED; case 404: /* Not found */ return AST_CAUSE_UNALLOCATED; - case 483: /* Too many hops */ + case 408: /* No reaction */ + return AST_CAUSE_NO_USER_RESPONSE; + case 480: /* No answer */ return AST_CAUSE_FAILURE; - case 486: + case 483: /* Too many hops */ + return AST_CAUSE_NO_ANSWER; + case 486: /* Busy everywhere */ return AST_CAUSE_BUSY; + case 488: /* No codecs approved */ + return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; + 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; default: return AST_CAUSE_NORMAL; } @@ -1883,24 +1896,85 @@ static int hangup_sip2cause(int cause) return 0; } + /*--- hangup_cause2sip: Convert Asterisk hangup causes to SIP codes ---*/ +/* Possible values from causes.h + AST_CAUSE_NOTDEFINED AST_CAUSE_NORMAL AST_CAUSE_BUSY + AST_CAUSE_FAILURE AST_CAUSE_CONGESTION AST_CAUSE_UNALLOCATED + + In addition to these, a lot of PRI codes is defined in causes.h + ...should we take care of them too ? + + Quote RFC 3398 + + ISUP Cause value SIP response + ---------------- ------------ + 1 unallocated number 404 Not Found + 2 no route to network 404 Not found + 3 no route to destination 404 Not found + 16 normal call clearing --- (*) + 17 user busy 486 Busy here + 18 no user responding 408 Request Timeout + 19 no answer from the user 480 Temporarily unavailable + 20 subscriber absent 480 Temporarily unavailable + 21 call rejected 403 Forbidden (+) + 22 number changed (w/o diagnostic) 410 Gone + 22 number changed (w/ diagnostic) 301 Moved Permanently + 23 redirection to new destination 410 Gone + 26 non-selected user clearing 404 Not Found (=) + 27 destination out of order 502 Bad Gateway + 28 address incomplete 484 Address incomplete + 29 facility rejected 501 Not implemented + 31 normal unspecified 480 Temporarily unavailable +*/ static char *hangup_cause2sip(int cause) { switch(cause) { + case AST_CAUSE_UNALLOCATED: /* 1 */ + case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ + case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ + return "404 Not Found"; + case AST_CAUSE_CONGESTION: /* 34 */ + case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ + return "503 Service Unavailable"; + case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ + return "408 Request Timeout"; + case AST_CAUSE_NO_ANSWER: /* 19 */ + return "480 Temporarily unavailable"; + case AST_CAUSE_CALL_REJECTED: /* 21 */ + return "403 Forbidden"; + case AST_CAUSE_NUMBER_CHANGED: /* 22 */ + return "410 Gone"; + case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ + return "480 Temporarily unavailable"; + case AST_CAUSE_INVALID_NUMBER_FORMAT: + return "484 Address incomplete"; + case AST_CAUSE_USER_BUSY: + return "486 Busy here"; case AST_CAUSE_FAILURE: return "500 Server internal failure"; - case AST_CAUSE_CONGESTION: + case AST_CAUSE_FACILITY_REJECTED: /* 29 */ + return "501 Not Implemented"; + case AST_CAUSE_CHAN_NOT_IMPLEMENTED: return "503 Service Unavailable"; - case AST_CAUSE_BUSY: - return "486 Busy"; + /* Used in chan_iax2 */ + case AST_CAUSE_DESTINATION_OUT_OF_ORDER: + return "502 Bad Gateway"; + case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ + return "488 Not Acceptable Here"; + + case AST_CAUSE_NOTDEFINED: default: + ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); return NULL; } + /* Never reached */ return 0; } + /*--- sip_hangup: Hangup SIP call ---*/ /* Part of PBX interface */ static int sip_hangup(struct ast_channel *ast)