changeset 63:e5aee661e3b2

sip-in: beginning to handle incoming MNCC messages from themwi-mncc
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 18 Sep 2022 15:01:11 -0800
parents 75b7a7b61824
children 1f863c63f96b
files sip-in/Makefile sip-in/call.h sip-in/call_list.c sip-in/call_setup.c sip-in/mncc_handle.c sip-in/mncc_sock.c
diffstat 6 files changed, 188 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/sip-in/Makefile	Sat Sep 17 18:43:08 2022 -0800
+++ b/sip-in/Makefile	Sun Sep 18 15:01:11 2022 -0800
@@ -2,7 +2,7 @@
 CFLAGS=	-O2
 PROG=	themwi-sip-in
 OBJS=	call_list.o call_setup.o invite.o main.o mgw_ops.o mgw_sock.o \
-	mncc_sock.o readconf.o sip_log.o sip_uas.o sip_udp.o
+	mncc_handle.o mncc_sock.o readconf.o sip_log.o sip_uas.o sip_udp.o
 LIBS=	../libnumdb/libnumdb.a ../libsip/libsip.a ../libutil/libutil.a
 INSTBIN=/usr/local/bin
 
--- a/sip-in/call.h	Sat Sep 17 18:43:08 2022 -0800
+++ b/sip-in/call.h	Sun Sep 18 15:01:11 2022 -0800
@@ -36,10 +36,10 @@
 	uint32_t	mgw_xact;
 	uint32_t	mgw_xact_id;
 	uint32_t	sdp_addend;
+	uint32_t	mncc_state;
+	uint32_t	mncc_callref;
 	char		invite_fail[80];
 	unsigned	sip_tx_count;
-	int		mncc_active;
-	uint32_t	mncc_callref;
 };
 
 #define	OVERALL_STATE_CRCX		1
@@ -60,6 +60,14 @@
 #define	SIP_STATE_ENDED			8
 #define	SIP_STATE_MSG_SIZE_ERR		9
 
+#define	MNCC_STATE_NO_EXIST		0
+#define	MNCC_STATE_STARTED		1
+#define	MNCC_STATE_ALERTING		2
+#define	MNCC_STATE_ANSWERED		3
+#define	MNCC_STATE_CONNECTED		4
+#define	MNCC_STATE_DISCONNECT		5
+#define	MNCC_STATE_RELEASE		6
+
 #define	MGW_STATE_NO_EXIST		0
 #define	MGW_STATE_ALLOCATED		1
 #define	MGW_STATE_CONNECTING		2
--- a/sip-in/call_list.c	Sat Sep 17 18:43:08 2022 -0800
+++ b/sip-in/call_list.c	Sun Sep 18 15:01:11 2022 -0800
@@ -34,7 +34,7 @@
 	struct call *call;
 
 	for (call = call_list; call; call = call->next)
-		if (call->mncc_active && call->mncc_callref == callref)
+		if (call->mncc_state && call->mncc_callref == callref)
 			return call;
 	return 0;
 }
@@ -47,7 +47,6 @@
 	for (;;) {
 		next_callref++;
 		if (!find_call_by_mncc_callref(next_callref)) {
-			call->mncc_active = 1;
 			call->mncc_callref = next_callref;
 			return(0);
 		}
--- a/sip-in/call_setup.c	Sat Sep 17 18:43:08 2022 -0800
+++ b/sip-in/call_setup.c	Sun Sep 18 15:01:11 2022 -0800
@@ -67,4 +67,5 @@
 	setup_msg.fields |= MNCC_F_CALLING;
 	send_mncc_to_gsm(&setup_msg, sizeof(struct gsm_mncc));
 	call->overall_state = OVERALL_STATE_CALL_GSM;
+	call->mncc_state = MNCC_STATE_STARTED;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sip-in/mncc_handle.c	Sun Sep 18 15:01:11 2022 -0800
@@ -0,0 +1,174 @@
+/*
+ * In this module we implement our handling of call control messages
+ * from OsmoMSC relayed to us via themwi-mncc.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <syslog.h>
+#include "../include/mncc.h"
+#include "../include/gsm48_const.h"
+#include "call.h"
+
+extern struct call *find_call_by_mncc_callref();
+
+static void
+handle_alerting(call, msg)
+	struct call *call;
+	struct gsm_mncc *msg;
+{
+	/* handling to be implemented */
+}
+
+static void
+handle_answer(call, msg)
+	struct call *call;
+	struct gsm_mncc *msg;
+{
+	/* handling to be implemented */
+}
+
+static void
+handle_disconnect_ind(call, msg)
+	struct call *call;
+	struct gsm_mncc *msg;
+{
+	/* handling to be implemented */
+}
+
+static void
+handle_final_release(call, msg)
+	struct call *call;
+	struct gsm_mncc *msg;
+{
+	/* handling to be implemented */
+}
+
+static void
+handle_signaling_msg(msg, msglen)
+	struct gsm_mncc *msg;
+	unsigned msglen;
+{
+	struct call *call;
+
+	if (msglen != sizeof(struct gsm_mncc)) {
+		syslog(LOG_CRIT,
+			"FATAL: Rx MNCC message type 0x%x has wrong length",
+			msg->msg_type);
+		exit(1);
+	}
+	call = find_call_by_mncc_callref(msg->callref);
+	if (!call) {
+		syslog(LOG_CRIT,
+		"error: Rx MNCC message type 0x%x has invalid callref 0x%x",
+			msg->msg_type, msg->callref);
+		exit(1);
+	}
+	switch (msg->msg_type) {
+	case MNCC_SETUP_CNF:
+		handle_answer(call, msg);
+		return;
+	case MNCC_ALERT_IND:
+		handle_alerting(call, msg);
+		return;
+	case MNCC_DISC_IND:
+		handle_disconnect_ind(call, msg);
+		return;
+	case MNCC_REL_IND:
+	case MNCC_REL_CNF:
+	case MNCC_REJ_IND:
+		handle_final_release(call, msg);
+		return;
+	case MNCC_START_DTMF_IND:
+		msg->msg_type = MNCC_START_DTMF_REJ;
+		mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
+		send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
+		return;
+	case MNCC_STOP_DTMF_IND:
+		msg->msg_type = MNCC_STOP_DTMF_RSP;
+		send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
+		return;
+	case MNCC_MODIFY_IND:
+		msg->msg_type = MNCC_MODIFY_REJ;
+		mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
+		send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
+		return;
+	case MNCC_HOLD_IND:
+		msg->msg_type = MNCC_HOLD_REJ;
+		mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
+		send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
+		return;
+	case MNCC_RETRIEVE_IND:
+		msg->msg_type = MNCC_RETRIEVE_REJ;
+		mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
+		send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
+		return;
+	}
+}
+
+static void
+handle_rtp_create(msg, msglen)
+	struct gsm_mncc_rtp *msg;
+	unsigned msglen;
+{
+	struct call *call;
+
+	if (msglen != sizeof(struct gsm_mncc_rtp)) {
+		syslog(LOG_CRIT,
+			"FATAL: Rx MNCC message type 0x%x has wrong length",
+			msg->msg_type);
+		exit(1);
+	}
+	call = find_call_by_mncc_callref(msg->callref);
+	if (!call) {
+		syslog(LOG_CRIT,
+		"error: Rx MNCC message type 0x%x has invalid callref 0x%x",
+			msg->msg_type, msg->callref);
+		exit(1);
+	}
+	/* handling to be implemented */
+}
+
+void
+msg_from_mncc(msg, msglen)
+	union mncc_msg *msg;
+	unsigned msglen;
+{
+	switch (msg->msg_type) {
+	case MNCC_SETUP_CNF:
+	case MNCC_CALL_CONF_IND:
+	case MNCC_ALERT_IND:
+	case MNCC_NOTIFY_IND:
+	case MNCC_DISC_IND:
+	case MNCC_FACILITY_IND:
+	case MNCC_START_DTMF_IND:
+	case MNCC_STOP_DTMF_IND:
+	case MNCC_MODIFY_IND:
+	case MNCC_HOLD_IND:
+	case MNCC_RETRIEVE_IND:
+	case MNCC_USERINFO_IND:
+	case MNCC_REL_IND:
+	case MNCC_REL_CNF:
+	case MNCC_REJ_IND:
+		handle_signaling_msg(msg, msglen);
+		return;
+	case MNCC_RTP_CREATE:
+		handle_rtp_create(msg, msglen);
+		return;
+	default:
+		syslog(LOG_CRIT,
+			"FATAL: received unexpected MNCC message type 0x%x",
+			msg->msg_type);
+		exit(1);
+	}
+}
--- a/sip-in/mncc_sock.c	Sat Sep 17 18:43:08 2022 -0800
+++ b/sip-in/mncc_sock.c	Sun Sep 18 15:01:11 2022 -0800
@@ -57,7 +57,7 @@
 		syslog(LOG_CRIT, "short read from mtcall socket: %d bytes", rc);
 		exit(1);
 	}
-	/* mncc_msg_from_gsm(&msg, rc); */
+	msg_from_mncc(&msg, rc);
 }
 
 send_mncc_to_gsm(msg, msglen)