diff options
Diffstat (limited to 'src/libosmocc/cause.c')
-rw-r--r-- | src/libosmocc/cause.c | 252 |
1 files changed, 0 insertions, 252 deletions
diff --git a/src/libosmocc/cause.c b/src/libosmocc/cause.c deleted file mode 100644 index 4a3a41e..0000000 --- a/src/libosmocc/cause.c +++ /dev/null @@ -1,252 +0,0 @@ -/* OSMO-CC Processing: convert causes - * - * (C) 2019 by Andreas Eversberg <jolly@eversberg.eu> - * All Rights Reserved - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdint.h> -#include <arpa/inet.h> -#include "message.h" -#include "cause.h" - -/* stolen from freeswitch */ -/* map sip responses to QSIG cause codes ala RFC4497 section 8.4.4 */ -static uint8_t status2isdn_cause(uint16_t status) -{ - switch (status) { - case 200: - return 16; //SWITCH_CAUSE_NORMAL_CLEARING; - case 401: - case 402: - case 403: - case 407: - case 603: - return 21; //SWITCH_CAUSE_CALL_REJECTED; - case 404: - return 1; //SWITCH_CAUSE_UNALLOCATED_NUMBER; - case 485: - case 604: - return 3; //SWITCH_CAUSE_NO_ROUTE_DESTINATION; - case 408: - case 504: - return 102; //SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE; - case 410: - return 22; //SWITCH_CAUSE_NUMBER_CHANGED; - case 413: - case 414: - case 416: - case 420: - case 421: - case 423: - case 505: - case 513: - return 127; //SWITCH_CAUSE_INTERWORKING; - case 480: - return 180; //SWITCH_CAUSE_NO_USER_RESPONSE; - case 400: - case 481: - case 500: - case 503: - return 41; //SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE; - case 486: - case 600: - return 17; //SWITCH_CAUSE_USER_BUSY; - case 484: - return 28; //SWITCH_CAUSE_INVALID_NUMBER_FORMAT; - case 488: - case 606: - return 88; //SWITCH_CAUSE_INCOMPATIBLE_DESTINATION; - case 502: - return 38; //SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; - case 405: - return 63; //SWITCH_CAUSE_SERVICE_UNAVAILABLE; - case 406: - case 415: - case 501: - return 79; //SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED; - case 482: - case 483: - return 25; //SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR; - case 487: - return 31; //??? SWITCH_CAUSE_ORIGINATOR_CANCEL; - default: - return 31; //SWITCH_CAUSE_NORMAL_UNSPECIFIED; - } -} - -static uint16_t isdn2status_cause(uint8_t cause, uint8_t location) -{ - switch (cause) { - case 1: - return 404; - case 2: - return 404; - case 3: - return 404; - case 17: - return 486; - case 18: - return 408; - case 19: - return 480; - case 20: - return 480; - case 21: - if (location == OSMO_CC_LOCATION_USER) - return 603; - return 403; - case 22: - //return 301; - return 410; - case 23: - return 410; - case 26: - return 404; - case 27: - return 502; - case 28: - return 484; - case 29: - return 501; - case 31: - return 480; - case 34: - return 503; - case 38: - return 503; - case 41: - return 503; - case 42: - return 503; - case 47: - return 503; - case 55: - return 403; - case 57: - return 403; - case 58: - return 503; - case 65: - return 488; - case 69: - return 501; - case 70: - return 488; - case 79: - return 501; - case 87: - return 403; - case 88: - return 503; - case 102: - return 504; - case 111: - return 500; - case 127: - return 500; - default: - return 468; - } -} - -static uint8_t socket2isdn_cause(uint8_t sock) -{ - switch (sock) { - case OSMO_CC_SOCKET_CAUSE_FAILED: - return 47; - case OSMO_CC_SOCKET_CAUSE_BROKEN_PIPE: - return 41; - case OSMO_CC_SOCKET_CAUSE_VERSION_MISMATCH: - return 38; - case OSMO_CC_SOCKET_CAUSE_TIMEOUT: - return 41; - default: - return 31; - } -} - -void osmo_cc_convert_cause(struct osmo_cc_ie_cause *cause) -{ - /* complete cause, from socket cause */ - if (cause->socket_cause && cause->isdn_cause == 0 && ntohs(cause->sip_cause_networkorder) == 0) - cause->isdn_cause = socket2isdn_cause(cause->socket_cause); - - /* convert ISDN cause to SIP cause */ - if (cause->isdn_cause && ntohs(cause->sip_cause_networkorder) == 0) { - cause->sip_cause_networkorder = htons(isdn2status_cause(cause->isdn_cause, cause->location)); - } - - /* convert SIP cause to ISDN cause */ - if (ntohs(cause->sip_cause_networkorder) && cause->isdn_cause == 0) { - cause->isdn_cause = status2isdn_cause(ntohs(cause->sip_cause_networkorder)); - } - - /* no cause at all: use Normal Call Clearing */ - if (cause->isdn_cause == 0 && ntohs(cause->sip_cause_networkorder) == 0) { - cause->isdn_cause = OSMO_CC_ISDN_CAUSE_NORM_CALL_CLEAR; - cause->sip_cause_networkorder = htons(486); - } -} - -void osmo_cc_convert_cause_msg(osmo_cc_msg_t *msg) -{ - void *ie; - uint8_t type; - uint16_t length; - void *value; - - /* search for (all) cause IE and convert the values, if needed */ - ie = msg->data; - while ((value = osmo_cc_msg_sep_ie(msg, &ie, &type, &length))) { - if (type == OSMO_CC_IE_CAUSE && length >= sizeof(struct osmo_cc_ie_cause)) { - osmo_cc_convert_cause(value); - } - } -} - -uint8_t osmo_cc_collect_cause(uint8_t old_cause, uint8_t new_cause) -{ - /* first cause */ - if (old_cause == 0) - return new_cause; - - /* first prio: return 17 */ - if (old_cause == OSMO_CC_ISDN_CAUSE_USER_BUSY - || new_cause == OSMO_CC_ISDN_CAUSE_USER_BUSY) - return OSMO_CC_ISDN_CAUSE_USER_BUSY; - - /* second prio: return 21 */ - if (old_cause == OSMO_CC_ISDN_CAUSE_CALL_REJECTED - || new_cause == OSMO_CC_ISDN_CAUSE_CALL_REJECTED) - return OSMO_CC_ISDN_CAUSE_CALL_REJECTED; - - /* third prio: return other than 88 and 18 (what ever was first) */ - if (old_cause != OSMO_CC_ISDN_CAUSE_INCOMPAT_DEST - && old_cause != OSMO_CC_ISDN_CAUSE_USER_NOTRESPOND) - return old_cause; - if (new_cause != OSMO_CC_ISDN_CAUSE_INCOMPAT_DEST - && new_cause != OSMO_CC_ISDN_CAUSE_USER_NOTRESPOND) - return new_cause; - - /* fourth prio: return 88 */ - if (old_cause == OSMO_CC_ISDN_CAUSE_INCOMPAT_DEST - || new_cause == OSMO_CC_ISDN_CAUSE_INCOMPAT_DEST) - return OSMO_CC_ISDN_CAUSE_INCOMPAT_DEST; - - /* fith prio: return 18 */ - return OSMO_CC_ISDN_CAUSE_USER_NOTRESPOND; -} - |