diff sip-out/mncc_sock.c @ 154:e54b0a9e322f

beginning of themwi-sip-out
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 11 Oct 2022 23:04:01 -0800
parents mncc/mtsock.c@db7ed6a55ba4
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sip-out/mncc_sock.c	Tue Oct 11 23:04:01 2022 -0800
@@ -0,0 +1,153 @@
+/*
+ * In this module we implement the MNCC socket interface to themwi-sip-out.
+ * We have an outcall socket on which we accept connections, and each
+ * accepted connection becomes a struct mncc_conn for us.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <syslog.h>
+#include <unistd.h>
+#include "../include/mncc.h"
+#include "../include/out_routes.h"
+#include "call.h"
+
+static char outcall_socket_pathname[] = "/var/gsm/outcall_socket";
+
+int mncc_listener;
+struct mncc_conn *mncc_conn_list;
+
+create_outcall_socket()
+{
+	struct sockaddr_un sa;
+	unsigned sa_len;
+	int rc;
+
+	mncc_listener = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (mncc_listener < 0) {
+		syslog(LOG_CRIT, "socket(AF_UNIX, SOCK_SEQPACKET, 0): %m");
+		return(-1);
+	}
+	unlink(outcall_socket_pathname);
+	fill_sockaddr_un(outcall_socket_pathname, &sa, &sa_len);
+	rc = bind(mncc_listener, (struct sockaddr *) &sa, sa_len);
+	if (rc < 0) {
+		syslog(LOG_ERR, "bind to %s: %m", outcall_socket_pathname);
+		return(-1);
+	}
+	rc = listen(mncc_listener, 3);
+	if (rc < 0) {
+		syslog(LOG_CRIT, "listen on UNIX socket: %m");
+		return(-1);
+	}
+	chmod(outcall_socket_pathname, 0775);
+	update_max_fd(mncc_listener);
+	return(0);
+}
+
+void
+mncc_listener_select()
+{
+	struct sockaddr_un sa;
+	socklen_t sa_len;
+	int fd;
+	struct mncc_conn *conn;
+
+	sa_len = sizeof sa;
+	fd = accept(mncc_listener, (struct sockaddr *) &sa, &sa_len);
+	if (fd < 0) {
+		syslog(LOG_CRIT, "accept on UNIX socket: %m");
+		exit(1);
+	}
+	conn = malloc(sizeof(struct mncc_conn));
+	if (!conn) {
+		syslog(LOG_CRIT, "malloc for outcall socket conn: %m");
+		close(fd);
+		return;
+	}
+	syslog(LOG_INFO, "new outcall socket connection");
+	conn->fd = fd;
+	conn->next = mncc_conn_list;
+	mncc_conn_list = conn;
+	update_max_fd(fd);
+}
+
+static void
+dispatch_mncc_msg(mncc, msg, msglen)
+	struct mncc_conn *mncc;
+	union mncc_msg *msg;
+	unsigned msglen;
+{
+	switch (msg->msg_type) {
+	case MNCC_SETUP_IND:
+		handle_setup_ind(mncc, msg, msglen);
+		return;
+	case MNCC_SETUP_COMPL_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:
+		handle_mncc_signal(mncc, msg, msglen);
+		return;
+	case MNCC_RTP_CREATE:
+		handle_rtp_create(mncc, msg, msglen);
+		return;
+	case MNCC_RTP_CONNECT:
+		syslog(LOG_ERR, "MNCC_RTP_CONNECT error from OsmoMSC");
+		return;
+	case MNCC_RTP_FREE:
+		syslog(LOG_ERR, "MNCC_RTP_FREE bogon from OsmoMSC");
+		return;
+	default:
+		syslog(LOG_CRIT,
+			"FATAL: received unexpected MNCC message type 0x%x",
+			msg->msg_type);
+		exit(1);
+	}
+}
+
+void
+mncc_socket_select(conn)
+	struct mncc_conn *conn;
+{
+	union mncc_msg msg;
+	int rc;
+
+	rc = recv(conn->fd, &msg, sizeof msg, 0);
+	if (rc <= 0) {
+		syslog(LOG_ERR, "outcall socket disconnected");
+		close(conn->fd);
+		conn->fd = -1;
+		shutdown_mncc_socket(conn);
+		return;
+	}
+	if (rc < 4) {
+		syslog(LOG_CRIT, "short read from MNCC socket: %d bytes", rc);
+		exit(1);
+	}
+	dispatch_mncc_msg(conn, &msg, rc);
+}
+
+send_mncc_to_sock(mncc, msg, msglen)
+	struct mncc_conn *mncc;
+	union mncc_msg *msg;
+	unsigned msglen;
+{
+	return send(mncc->fd, msg, msglen, 0);
+}