Change in osmo-msc[master]: libmsc/gsm_04_11.c: forward MO SMS messages over GSUP

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Sun Nov 25 15:36:13 UTC 2018


Vadim Yanitskiy has uploaded this change for review. ( https://gerrit.osmocom.org/11919


Change subject: libmsc/gsm_04_11.c: forward MO SMS messages over GSUP
......................................................................

libmsc/gsm_04_11.c: forward MO SMS messages over GSUP

Change-Id: I7d651fde3d608d02f275a74043dc42262aabb1b8
Depends-on: (core) Ibe325c64ae2d6c626b232533bb4cbc65fc2b5d71
Related: OS#3587
---
M include/osmocom/msc/Makefile.am
M include/osmocom/msc/gsm_04_11.h
A include/osmocom/msc/gsm_04_11_gsup.h
M src/libmsc/Makefile.am
M src/libmsc/gsm_04_08.c
M src/libmsc/gsm_04_11.c
A src/libmsc/gsm_04_11_gsup.c
7 files changed, 292 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/19/11919/1

diff --git a/include/osmocom/msc/Makefile.am b/include/osmocom/msc/Makefile.am
index ebc946a..8674b75 100644
--- a/include/osmocom/msc/Makefile.am
+++ b/include/osmocom/msc/Makefile.am
@@ -7,6 +7,7 @@
 	debug.h \
 	gsm_04_08.h \
 	gsm_04_11.h \
+	gsm_04_11_gsup.h \
 	gsm_04_14.h \
 	gsm_04_80.h \
 	gsm_09_11.h \
diff --git a/include/osmocom/msc/gsm_04_11.h b/include/osmocom/msc/gsm_04_11.h
index a368d46..3997ab2 100644
--- a/include/osmocom/msc/gsm_04_11.h
+++ b/include/osmocom/msc/gsm_04_11.h
@@ -2,6 +2,7 @@
 #define _GSM_04_11_H
 
 #include <osmocom/gsm/protocol/gsm_04_11.h>
+#include <osmocom/msc/gsm_04_11_gsup.h>
 
 struct vlr_subscr;
 struct gsm_subscriber_connection;
diff --git a/include/osmocom/msc/gsm_04_11_gsup.h b/include/osmocom/msc/gsm_04_11_gsup.h
new file mode 100644
index 0000000..82f575d
--- /dev/null
+++ b/include/osmocom/msc/gsm_04_11_gsup.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <stdint.h>
+
+/* Forward declarations */
+struct osmo_gsup_message;
+struct vlr_subscr;
+struct gsm_trans;
+struct msgb;
+
+int gsm411_gsup_mo_ready_for_sm_req(struct gsm_trans *trans, uint8_t sm_rp_mr);
+int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg,
+	uint8_t sm_rp_mr, uint8_t *sm_rp_da, uint8_t sm_rp_da_len);
+int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,
+	struct osmo_gsup_message *gsup_msg);
diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am
index 90bbbf8..aa95265 100644
--- a/src/libmsc/Makefile.am
+++ b/src/libmsc/Makefile.am
@@ -35,6 +35,7 @@
 	gsm_04_08.c \
 	gsm_04_08_cc.c \
 	gsm_04_11.c \
+	gsm_04_11_gsup.c \
 	gsm_04_14.c \
 	gsm_04_80.c \
 	gsm_09_11.c \
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index d5cc212..161585c 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -1784,6 +1784,14 @@
 		DEBUGP(DMSC, "Routed to GSM 09.11 SS/USSD handler\n");
 		return gsm0911_gsup_handler(vsub, gsup_msg);
 
+	/* GSM 04.11 code implementing MO SMS */
+	case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
+	case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
+	case OSMO_GSUP_MSGT_READY_FOR_SM_ERROR:
+	case OSMO_GSUP_MSGT_READY_FOR_SM_RESULT:
+		DEBUGP(DMSC, "Routed to GSM 04.11 MO handler\n");
+		return gsm411_gsup_mo_handler(vsub, gsup_msg);
+
 	default:
 		LOGP(DMM, LOGL_ERROR, "No handler found for %s, dropping message...\n",
 			osmo_gsup_message_type_name(gsup_msg->message_type));
diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c
index d4025c8..93c2ea7 100644
--- a/src/libmsc/gsm_04_11.c
+++ b/src/libmsc/gsm_04_11.c
@@ -666,10 +666,14 @@
 
 /* Receive a 04.11 TPDU inside RP-DATA / user data */
 static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans,
-			  struct gsm411_rp_hdr *rph)
+			  struct gsm411_rp_hdr *rph,
+			  uint8_t *dst, uint8_t dst_len)
 {
 	int rc = 0;
 
+	if (trans->net->enable_sms_over_gsup)
+		goto sms_over_gsup;
+
 	rc = gsm340_rx_tpdu(trans, msg, rph->msg_ref);
 	if (rc == 0)
 		return gsm411_send_rp_ack(trans, rph->msg_ref);
@@ -677,6 +681,14 @@
 		return gsm411_send_rp_error(trans, rph->msg_ref, rc);
 	else
 		return rc;
+
+sms_over_gsup:
+	/* RP-ACK or RP-ERROR is triggered as soon as we get the response */
+	rc = gsm411_gsup_mo_fwd_sm_req(trans, msg, rph->msg_ref, dst, dst_len);
+	if (rc) /* GSUP message sending error */
+		return gsm411_send_rp_error(trans, rph->msg_ref, rc);
+
+	return 0;
 }
 
 /* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
@@ -717,7 +729,7 @@
 
 	DEBUGP(DLSMS, "DST(%u,%s)\n", dst_len, osmo_hexdump(dst, dst_len));
 
-	return gsm411_rx_rp_ud(msg, trans, rph);
+	return gsm411_rx_rp_ud(msg, trans, rph, dst, dst_len);
 }
 
 static struct gsm_sms *sms_report_alloc(struct gsm_sms *sms)
@@ -854,6 +866,9 @@
 {
 	int rc;
 
+	if (trans->net->enable_sms_over_gsup)
+		goto sms_over_gsup;
+
 	rc = gsm411_send_rp_ack(trans, rph->msg_ref);
 
 	/* MS tells us that it has memory for more SMS, we need
@@ -862,6 +877,14 @@
 	send_signal(S_SMS_SMMA, trans, NULL, 0);
 
 	return rc;
+
+sms_over_gsup:
+	/* RP-ACK or RP-ERROR is triggered as soon as we get the response */
+	rc = gsm411_gsup_mo_ready_for_sm_req(trans, rph->msg_ref);
+	if (rc) /* GSUP message sending error */
+		return gsm411_send_rp_error(trans, rph->msg_ref, rc);
+
+	return 0;
 }
 
 /* receive RL DATA */
diff --git a/src/libmsc/gsm_04_11_gsup.c b/src/libmsc/gsm_04_11_gsup.c
new file mode 100644
index 0000000..ee06936
--- /dev/null
+++ b/src/libmsc/gsm_04_11_gsup.c
@@ -0,0 +1,241 @@
+/*
+ * (C) 2018 by Vadim Yanitskiy <axilirator at gmail.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+
+#include <osmocom/gsupclient/gsup_client.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/vlr.h>
+
+/* Common helper for preparing to be encoded GSUP message */
+static void gsup_msg_init(struct osmo_gsup_message *gsup_msg,
+	enum osmo_gsup_message_type msg_type, const char *imsi,
+	uint8_t *sm_rp_mr)
+{
+	/* Compose a mew GSUP message */
+	memset(gsup_msg, 0x00, sizeof(*gsup_msg));
+	gsup_msg->message_type = msg_type;
+
+	/* SM-RP-MR (Message Reference) */
+	gsup_msg->sm_rp_mr = sm_rp_mr;
+
+	/* Fill in subscriber's IMSI */
+	OSMO_STRLCPY_ARRAY(gsup_msg->imsi, imsi);
+}
+
+/* Common helper for encoding and sending GSUP messages towards ESME */
+static int gsup_msg_send(struct gsm_network *net,
+	struct osmo_gsup_message *gsup_msg)
+{
+	struct msgb *gsup_msgb;
+	int rc;
+
+	/* Allocate GSUP message buffer */
+	gsup_msgb = osmo_gsup_client_msgb_alloc();
+	if (!gsup_msgb) {
+		LOGP(DLSMS, LOGL_ERROR, "Couldn't allocate GSUP message\n");
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	/* Encode GSUP message */
+	rc = osmo_gsup_encode(gsup_msgb, gsup_msg);
+	if (rc) {
+		LOGP(DLSMS, LOGL_ERROR, "Couldn't encode GSUP message\n");
+		goto error;
+	}
+
+	/* Finally send */
+	rc = osmo_gsup_client_send(net->vlr->gsup_client, gsup_msgb);
+	if (rc) {
+		LOGP(DLSMS, LOGL_ERROR, "Couldn't send GSUP message\n");
+		goto error;
+	}
+
+	return 0;
+
+error:
+	if (gsup_msgb)
+		talloc_free(gsup_msgb);
+
+	return rc;
+}
+
+int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg,
+	uint8_t sm_rp_mr, uint8_t *sm_rp_da, uint8_t sm_rp_da_len)
+{
+	uint8_t bcd_buf[GSM48_MI_SIZE] = { 0 };
+	struct osmo_gsup_message gsup_msg;
+	size_t bcd_len;
+
+	/* Associate logging messages with this subscriber */
+	log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
+
+	LOGP(DLSMS, LOGL_DEBUG, "TX GSUP MO-forwardSM-Req\n");
+
+	/* Assign SM-RP-MR to transaction state */
+	trans->sms.sm_rp_mr = sm_rp_mr;
+
+	/* Encode subscriber's MSISDN */
+	bcd_len = gsm48_encode_bcd_number(bcd_buf, sizeof(bcd_buf),
+		0, trans->vsub->msisdn);
+	if (bcd_len <= 0 || bcd_len > sizeof(bcd_buf)) {
+		LOGP(DLSMS, LOGL_ERROR, "Failed to encode subscriber's MSISDN\n");
+		return -EINVAL;
+	}
+
+	/* Initialize a new GSUP message */
+	gsup_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST,
+		trans->vsub->imsi, &sm_rp_mr);
+
+	/* According to 12.2.3, the MSISDN from VLR is inserted here */
+	gsup_msg.sm_rp_oa_type = OSMO_GSUP_SMS_SM_RP_ODA_MSISDN;
+	gsup_msg.sm_rp_oa_len = bcd_len;
+	gsup_msg.sm_rp_oa = bcd_buf;
+
+	/* SM-RP-DA should (already) contain SMSC address */
+	gsup_msg.sm_rp_da_type = OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR;
+	gsup_msg.sm_rp_da_len = sm_rp_da_len;
+	gsup_msg.sm_rp_da = sm_rp_da;
+
+	/* SM-RP-UI (TPDU) is pointed by msgb->l4h */
+	gsup_msg.sm_rp_ui_len = msgb_l4len(msg);
+	gsup_msg.sm_rp_ui = (uint8_t *) msgb_sms(msg);
+
+	return gsup_msg_send(trans->net, &gsup_msg);
+}
+
+int gsm411_gsup_mo_ready_for_sm_req(struct gsm_trans *trans, uint8_t sm_rp_mr)
+{
+	struct osmo_gsup_message gsup_msg;
+
+	/* Associate logging messages with this subscriber */
+	log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
+
+	LOGP(DLSMS, LOGL_DEBUG, "TX GSUP READY-FOR-SM Req\n");
+
+	/* Assign SM-RP-MR to transaction state */
+	trans->sms.sm_rp_mr = sm_rp_mr;
+
+	/* Initialize a new GSUP message */
+	gsup_msg_init(&gsup_msg, OSMO_GSUP_MSGT_READY_FOR_SM_REQUEST,
+		trans->vsub->imsi, &sm_rp_mr);
+
+	/* Indicate SMMA as the Alert Reason */
+	gsup_msg.sm_al_reas = OSMO_GSUP_SMS_SM_AL_REAS_MEM_AVAIL;
+
+	return gsup_msg_send(trans->net, &gsup_msg);
+}
+
+/* Triggers either RP-ACK or RP-ERROR on response from ESME */
+int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,
+	struct osmo_gsup_message *gsup_msg)
+{
+	struct gsm_subscriber_connection *conn;
+	struct vlr_instance *vlr;
+	struct gsm_network *net;
+	struct gsm_trans *trans;
+	const char *msg_name;
+	bool msg_is_err;
+
+	/* Obtain required pointers */
+	vlr = vsub->vlr;
+	net = (struct gsm_network *) vlr->user_ctx;
+
+	/* Associate logging messages with this subscriber */
+	log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
+
+	/* Determine the message type and name */
+	msg_is_err = OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type);
+	switch (gsup_msg->message_type) {
+	case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
+	case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
+		msg_name = "MO-forwardSM";
+		break;
+	case OSMO_GSUP_MSGT_READY_FOR_SM_ERROR:
+	case OSMO_GSUP_MSGT_READY_FOR_SM_RESULT:
+		msg_name = "MO-ReadyForSM";
+		break;
+	default:
+		/* Shall not happen */
+		OSMO_ASSERT(0);
+	}
+
+	LOGP(DLSMS, LOGL_DEBUG, "RX %s-%s\n", msg_name,
+		msg_is_err ? "Err" : "Res");
+
+	/* Make sure that 'SMS over GSUP' is expected */
+	if (!net->enable_sms_over_gsup) {
+		/* TODO: notify sender about that? */
+		LOGP(DLSMS, LOGL_NOTICE, "Unexpected MO SMS over GSUP, "
+			"ignoring message...\n");
+		return -EIO;
+	}
+
+	/* Verify GSUP message */
+	if (!gsup_msg->sm_rp_mr)
+		goto msg_error;
+	if (msg_is_err && !gsup_msg->sm_rp_cause)
+		goto msg_error;
+
+	/* Attempt to find a DTAP-connection */
+	conn = connection_for_subscr(vsub);
+	if (!conn) {
+		/* FIXME: should we establish it then? */
+		LOGP(DLSMS, LOGL_NOTICE, "No connection found for %s, "
+			"ignoring %s-%s message...\n", vlr_subscr_name(vsub),
+			msg_name, msg_is_err ? "Err" : "Res");
+		return -EIO; /* TODO: notify sender about that? */
+	}
+
+	/* Attempt to find DTAP-transaction */
+	trans = trans_find_by_sm_rp_mr(conn, *(gsup_msg->sm_rp_mr));
+	if (!trans) {
+		LOGP(DLSMS, LOGL_NOTICE, "No transaction found for %s, "
+			"ignoring %s-%s message...\n", vlr_subscr_name(vsub),
+			msg_name, msg_is_err ? "Err" : "Res");
+		return -EIO; /* TODO: notify sender about that? */
+	}
+
+	/* Send either RP-ERROR, or RP-ACK */
+	if (msg_is_err) {
+		/* TODO: handle optional SM-RP-UI payload (requires API change) */
+		gsm411_send_rp_error(trans, *(gsup_msg->sm_rp_mr),
+			*(gsup_msg->sm_rp_cause));
+	} else {
+		gsm411_send_rp_ack(trans, *(gsup_msg->sm_rp_mr));
+	}
+
+	return 0;
+
+msg_error:
+	/* TODO: notify sender about that? */
+	LOGP(DLSMS, LOGL_NOTICE, "RX malformed %s-%s\n",
+		msg_name, msg_is_err ? "Err" : "Res");
+	return -EINVAL;
+}

-- 
To view, visit https://gerrit.osmocom.org/11919
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7d651fde3d608d02f275a74043dc42262aabb1b8
Gerrit-Change-Number: 11919
Gerrit-PatchSet: 1
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20181125/e854ebf4/attachment.htm>


More information about the gerrit-log mailing list