changeset 83:3e3fbf44f9d7

sip-in: disconnect and call clearing implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 20 Sep 2022 22:06:37 -0800
parents ff4b76a107a1
children f82157ac7303
files sip-in/disconnect.c sip-in/mncc_handle.c sip-in/sip_ack.c
diffstat 3 files changed, 95 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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 <strings.h>
 #include <syslog.h>
 #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;
+	}
+}
--- 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
--- 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;