diff smsc-daemon/gsup_rx.c @ 3:8680979baeb1

smsc-daemon: first version put together
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 17 Aug 2023 22:56:49 -0800
parents
children cef4677a4cf8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smsc-daemon/gsup_rx.c	Thu Aug 17 22:56:49 2023 -0800
@@ -0,0 +1,118 @@
+/*
+ * This C module is part of proto-smsc-daemon concoction, a prototype/test
+ * implementation of a GSUP-based GSM SMSC.  It is based on the osmo-demo-euse
+ * program from OsmoHLR package.
+ *
+ * proto-smsc-daemon author: Mychaela N. Falconia <falcon@freecalypso.org>,
+ * no copyright.
+ *
+ * osmo-demo-euse author: Harald Welte <laforge@gnumonks.org>, (C) 2018, AGPL3+
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+
+#include <osmocom/gsm/gsup.h>
+
+#include <osmocom/gsupclient/gsup_client.h>
+
+#include "logging.h"
+
+extern void record_mo_sm(struct osmo_gsup_message *gmsg);
+
+static void send_gsup_response(struct osmo_gsup_client *gsupc,
+				struct osmo_gsup_message *orig_msg)
+{
+	struct osmo_gsup_message resp = {0};
+	struct msgb *resp_msg;
+
+	resp.message_type = OSMO_GSUP_TO_MSGT_RESULT(orig_msg->message_type);
+	OSMO_STRLCPY_ARRAY(resp.imsi, orig_msg->imsi);
+	resp.message_class = OSMO_GSUP_MESSAGE_CLASS_SMS;
+	resp.sm_rp_mr = orig_msg->sm_rp_mr;
+	resp.destination_name = orig_msg->source_name;
+	resp.destination_name_len = orig_msg->source_name_len;
+
+	resp_msg = osmo_gsup_client_msgb_alloc();
+	OSMO_ASSERT(resp_msg);
+	osmo_gsup_encode(resp_msg, &resp);
+	osmo_gsup_client_send(gsupc, resp_msg);
+}
+
+static void handle_mo_forward_sm(struct osmo_gsup_client *gsupc,
+				 struct osmo_gsup_message *gmsg)
+{
+	if (!gmsg->sm_rp_mr) {
+		LOGP(DMAIN, LOGL_ERROR,
+		     "error in MO-FORWARD-SM: missing SM-RP-MR\n");
+		return;
+	}
+	if (!gmsg->sm_rp_da_type) {
+		LOGP(DMAIN, LOGL_ERROR,
+		     "error in MO-FORWARD-SM: missing SM-RP-DA\n");
+		return;
+	}
+	if (!gmsg->sm_rp_oa_type) {
+		LOGP(DMAIN, LOGL_ERROR,
+		     "error in MO-FORWARD-SM: missing SM-RP-OA\n");
+		return;
+	}
+	if (!gmsg->sm_rp_ui) {
+		LOGP(DMAIN, LOGL_ERROR,
+		     "error in MO-FORWARD-SM: missing SM-RP-UI\n");
+		return;
+	}
+	record_mo_sm(gmsg);
+	send_gsup_response(gsupc, gmsg);
+}
+
+static void handle_ready_for_sm(struct osmo_gsup_client *gsupc,
+				struct osmo_gsup_message *gmsg)
+{
+	if (!gmsg->sm_rp_mr) {
+		LOGP(DMAIN, LOGL_ERROR,
+		     "error in READY-FOR-SM: missing SM-RP-MR\n");
+		return;
+	}
+	send_gsup_response(gsupc, gmsg);
+}
+
+int gsupc_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg)
+{
+	struct osmo_gsup_message gsup_msg = {0};
+	int rc;
+
+	rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup_msg);
+	if (rc < 0) {
+		LOGP(DMAIN, LOGL_ERROR, "Error decoding GSUP: %s\n", msgb_hexdump(msg));
+		return rc;
+	}
+	DEBUGP(DMAIN, "Rx GSUP %s: %s\n", osmo_gsup_message_type_name(gsup_msg.message_type),
+		msgb_hexdump(msg));
+
+	switch (gsup_msg.message_type) {
+	case OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST:
+		handle_mo_forward_sm(gsupc, &gsup_msg);
+		break;
+	case OSMO_GSUP_MSGT_READY_FOR_SM_REQUEST:
+		handle_ready_for_sm(gsupc, &gsup_msg);
+		break;
+	default:
+		LOGP(DMAIN, LOGL_ERROR, "Unhandled GSUP message type %s\n",
+			osmo_gsup_message_type_name(gsup_msg.message_type));
+		break;
+	}
+
+	msgb_free(msg);
+	return 0;
+}