changeset 259:9f96e5b14755

sip-out: implement E911 special handling
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 15 Aug 2023 11:28:30 -0800
parents aab047d9efcb
children b997de027717
files sip-out/Makefile sip-out/call_setup.c sip-out/e911.c
diffstat 3 files changed, 59 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/sip-out/Makefile	Tue Aug 15 10:54:16 2023 -0800
+++ b/sip-out/Makefile	Tue Aug 15 11:28:30 2023 -0800
@@ -1,10 +1,10 @@
 CC=	gcc
 CFLAGS=	-O2
 PROG=	themwi-sip-out
-OBJS=	bye_in.o call_clear.o call_list.o call_setup.o disconnect.o invite.o \
-	main.o mgw_ops.o mgw_resp.o mgw_sock.o mncc_sig_in.o mncc_sig_out.o \
-	mncc_sock.o readconf.o reinvite.o retrans.o shutdown.o sip_log.o \
-	sip_uas.o sip_udp.o uac_out.o uac_resp.o
+OBJS=	bye_in.o call_clear.o call_list.o call_setup.o disconnect.o e911.o \
+	invite.o main.o mgw_ops.o mgw_resp.o mgw_sock.o mncc_sig_in.o \
+	mncc_sig_out.o mncc_sock.o readconf.o reinvite.o retrans.o shutdown.o \
+	sip_log.o sip_uas.o sip_udp.o uac_out.o uac_resp.o
 LIBS=	../liboutrt/liboutrt.a ../libnumdb2/libnumdb.a ../libsip/libsip.a \
 	../libutil/libutil.a
 INSTBIN=/usr/local/bin
--- a/sip-out/call_setup.c	Tue Aug 15 10:54:16 2023 -0800
+++ b/sip-out/call_setup.c	Tue Aug 15 11:28:30 2023 -0800
@@ -117,6 +117,7 @@
 		}
 		to_sip_user[0] = '+';
 		strcpy(to_sip_user+1, msg->called.number);
+		special_rt = 0;
 	} else {
 		rc = route_special_number(msg->called.number, &dest,
 					  &special_rt);
@@ -141,6 +142,12 @@
 				GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
 		return;
 	}
+	/* E911 special handling */
+	if (special_rt && special_rt->flags & SPECIAL_NUM_FLAG_E911) {
+		rc = e911_call_preen(msg);
+		if (!rc)
+			goto call_barred;
+	}
 	/* TMGW must be up and running */
 	rc = connect_tmgw_socket();
 	if (rc < 0) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sip-out/e911.c	Tue Aug 15 11:28:30 2023 -0800
@@ -0,0 +1,48 @@
+/*
+ * In this module we implement E911 routing, i.e., special handling
+ * for calls to either the real 911 or E911 test numbers.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.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 "../include/number_db_v2.h"
+#include "../libnumdb2/lookup_func.h"
+
+e911_call_preen(msg)
+	struct gsm_mncc *msg;
+{
+	struct owned_number_rec *nr;
+
+	syslog(LOG_NOTICE, "E911 call attempt from %s to %s, emergency flag %d",
+		msg->calling.number, msg->called.number, msg->emergency);
+	refresh_number_db();
+	nr = numdb_lookup_nanp(msg->calling.number+1);
+	if (!nr) {
+		syslog(LOG_NOTICE,
+		"E911 call rejected: calling number is not in database");
+		return 0;
+	}
+	if (nr->number_flags & NUMBER_FLAG_E911PROV) {
+		syslog(LOG_NOTICE,
+			"E911 call allowed: calling number has E911 flag set");
+		return 1;
+	}
+	if (nr->usage & NUMBER_USAGE_FLAG_E911_VIA) {
+		sprintf(msg->calling.number, "1%03u%03u%04u",
+			nr->remap[0], nr->remap[1], nr->remap[2]);
+		syslog(LOG_NOTICE, "E911 call: source number changed to %s",
+			msg->calling.number);
+		return 1;
+	}
+	syslog(LOG_NOTICE,
+		"E911 call rejected: calling number is not E911-provisioned");
+	return 0;
+}