# HG changeset patch # User Mychaela Falconia # Date 1663740397 28800 # Node ID 3e3fbf44f9d73b12987a26893f88c0ffb27e258c # Parent ff4b76a107a1112ad548a86de27f67987d4b435f sip-in: disconnect and call clearing implemented diff -r ff4b76a107a1 -r 3e3fbf44f9d7 sip-in/disconnect.c --- a/sip-in/disconnect.c Tue Sep 20 20:33:09 2022 -0800 +++ b/sip-in/disconnect.c Tue Sep 20 22:06:37 2022 -0800 @@ -12,6 +12,7 @@ #include #include #include "../include/mncc.h" +#include "../include/gsm48_const.h" #include "call.h" void @@ -54,3 +55,52 @@ exit(1); } } + +static char * +cause_to_invite_err(cause) + struct gsm_mncc_cause *cause; +{ + switch (cause->value) { + case GSM48_CC_CAUSE_CALL_REJECTED: + return "403 Call rejected"; + case GSM48_CC_CAUSE_UNASSIGNED_NR: + return "404 Unassigned number"; + case GSM48_CC_CAUSE_USER_NOTRESPOND: + return "480 User not responding"; + case GSM48_CC_CAUSE_RESOURCE_UNAVAIL: + return "503 GSM network resource unavailable"; + case GSM48_CC_CAUSE_TEMP_FAILURE: + return "503 Temporary failure"; + case GSM48_CC_CAUSE_SWITCH_CONG: + return "503 Switch congestion at MSC"; + case GSM48_CC_CAUSE_USER_BUSY: + return "486 User busy"; + case GSM48_CC_CAUSE_DEST_OOO: + return "502 Destination out of order"; + case GSM48_CC_CAUSE_NETWORK_OOO: + return "503 Network out of order"; + default: + return "480 Unavailable (unspecified)"; + } +} + +void +disconnect_sip(call, cause) + struct call *call; + struct gsm_mncc_cause *cause; +{ + switch (call->sip_state) { + case SIP_STATE_INVITE_PROC: + case SIP_STATE_RINGING: + case SIP_STATE_RINGING_PRACK: + strcpy(call->invite_fail, cause_to_invite_err(cause)); + signal_invite_error(call); + break; + case SIP_STATE_INVITE_200: + /* have to wait for SIP ACK, then send BYE */ + break; + case SIP_STATE_CONNECTED: + initiate_bye(call); + break; + } +} diff -r ff4b76a107a1 -r 3e3fbf44f9d7 sip-in/mncc_handle.c --- a/sip-in/mncc_handle.c Tue Sep 20 20:33:09 2022 -0800 +++ b/sip-in/mncc_handle.c Tue Sep 20 22:06:37 2022 -0800 @@ -18,6 +18,12 @@ extern struct call *find_call_by_mncc_callref(); +static struct gsm_mncc_cause default_cause = { + .coding = GSM48_CAUSE_CODING_GSM, + .location = GSM48_CAUSE_LOC_PRN_S_LU, + .value = GSM48_CC_CAUSE_NORMAL_UNSPEC, +}; + static void handle_alerting(call, msg) struct call *call; @@ -54,7 +60,20 @@ struct call *call; struct gsm_mncc *msg; { - /* handling to be implemented */ + struct gsm_mncc_cause *cause; + + /* release back to MNCC */ + msg->msg_type = MNCC_REL_REQ; + send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + call->mncc_state = MNCC_STATE_RELEASE; + /* signal disconnect to SIP */ + call->overall_state = OVERALL_STATE_TEARDOWN; + if (msg->fields & MNCC_F_CAUSE) + cause = &msg->cause; + else + cause = &default_cause; + disconnect_sip(call, cause); + disconnect_tmgw(call); } static void @@ -62,7 +81,18 @@ struct call *call; struct gsm_mncc *msg; { - /* handling to be implemented */ + struct gsm_mncc_cause *cause; + + /* MNCC call leg is gone */ + call->mncc_state = MNCC_STATE_NO_EXIST; + /* signal disconnect to SIP */ + call->overall_state = OVERALL_STATE_TEARDOWN; + if (msg->fields & MNCC_F_CAUSE) + cause = &msg->cause; + else + cause = &default_cause; + disconnect_sip(call, cause); + disconnect_tmgw(call); } static void diff -r ff4b76a107a1 -r 3e3fbf44f9d7 sip-in/sip_ack.c --- a/sip-in/sip_ack.c Tue Sep 20 20:33:09 2022 -0800 +++ b/sip-in/sip_ack.c Tue Sep 20 22:06:37 2022 -0800 @@ -34,7 +34,19 @@ return; switch (call->sip_state) { case SIP_STATE_INVITE_200: - call->sip_state = SIP_STATE_CONNECTED; + switch (call->overall_state) { + case OVERALL_STATE_ANSWERED: + call->sip_state = SIP_STATE_CONNECTED; + break; + case OVERALL_STATE_TEARDOWN: + initiate_bye(call); + break; + default: + syslog(LOG_CRIT, + "FATAL: invalid overall state 0x%x on SIP ACK", + call->overall_state); + exit(1); + } break; case SIP_STATE_INVITE_ERR: call->sip_state = SIP_STATE_ENDED;