diff sip-in/mncc_handle.c @ 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
children 7c0309df59f8
line wrap: on
line diff
--- /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);
+	}
+}