Change in osmo-msc[master]: Add support for LCLS to the MSC

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/.

keith gerrit-no-reply at lists.osmocom.org
Sun May 16 01:51:54 UTC 2021


keith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-msc/+/24236 )


Change subject: Add support for LCLS to the MSC
......................................................................

Add support for LCLS to the MSC

This commit is largely based on work by
Max <msuraev at sysmocom.de>

Adds LCLS parameters for A-interface transactions
This commit also adds a vty option to facilitate globally
disabling LCLS for all calls on this MSC.

Add a global call reference (GCR) to MNCC and therefore
bump the MNCC version to version 8. (This commit has to be
merged at the same time as the corresponing commit in the
osmo-sip-connector for mncc-external use.)

Change-Id: I705c860e51637b4537cad65a330ecbaaca96dd5b
---
M include/osmocom/msc/debug.h
M include/osmocom/msc/gsm_data.h
M include/osmocom/msc/mncc.h
M include/osmocom/msc/ran_msg.h
M include/osmocom/msc/transaction.h
M src/libmsc/gsm_04_08_cc.c
M src/libmsc/msc_a.c
M src/libmsc/msc_vty.c
M src/libmsc/ran_msg_a.c
M src/libmsc/transaction.c
M src/osmo-msc/msc_main.c
M tests/mncc/mncc_test.ok
M tests/test_nodes.vty
13 files changed, 129 insertions(+), 12 deletions(-)



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

diff --git a/include/osmocom/msc/debug.h b/include/osmocom/msc/debug.h
index 3347e20..0d08ceb 100644
--- a/include/osmocom/msc/debug.h
+++ b/include/osmocom/msc/debug.h
@@ -8,6 +8,7 @@
 	DCC,
 	DMM,
 	DRR,
+	DLCLS,
 	DMNCC,
 	DPAG,
 	DMSC,
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index 1870804..f796004 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -257,6 +257,7 @@
 	/* Whether to use call waiting on the network */
 	bool call_waiting;
 	char *sms_db_file_path;
+	bool lcls_disable;
 };
 
 struct osmo_esme;
diff --git a/include/osmocom/msc/mncc.h b/include/osmocom/msc/mncc.h
index 1c8aff0..5002227 100644
--- a/include/osmocom/msc/mncc.h
+++ b/include/osmocom/msc/mncc.h
@@ -26,6 +26,7 @@
 
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/gsm/mncc.h>
+#include <osmocom/gsm/gsm29205.h>
 
 #include <stdint.h>
 #include <netinet/in.h>
@@ -160,7 +161,7 @@
 
 	unsigned char	lchan_type;
 	unsigned char	lchan_mode;
-
+	struct osmo_gcr_parsed gcr;
 	/* A buffer to contain SDP ('\0' terminated) */
 	char		sdp[1024];
 };
@@ -171,7 +172,7 @@
 	unsigned char	data[0];
 };
 
-#define MNCC_SOCK_VERSION	7
+#define MNCC_SOCK_VERSION	8
 struct gsm_mncc_hello {
 	uint32_t	msg_type;
 	uint32_t	version;
diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index 1303ba3..fd2439f 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -88,6 +88,7 @@
 	uint8_t osmux_cid;
 	bool call_id_present;
 	uint32_t call_id;
+	struct osmo_lcls *lcls;
 };
 
 struct ran_cipher_mode_command {
diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h
index 928b137..14b89bb 100644
--- a/include/osmocom/msc/transaction.h
+++ b/include/osmocom/msc/transaction.h
@@ -100,6 +100,7 @@
 			struct osmo_timer_list timer_guard;
 			struct gsm_mncc msg;	/* stores setup/disconnect/release message */
 			bool mncc_initiated;	/* Whether an MNCC Release is necessary on failure */
+			struct osmo_lcls *lcls;
 		} cc;
 		struct {
 			struct gsm411_smc_inst smc_inst;
@@ -145,6 +146,8 @@
 					 const struct vlr_subscr *vsub,
 					 uint8_t sm_rp_mr);
 
+struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac);
+
 struct gsm_trans *trans_alloc(struct gsm_network *net,
 			      struct vlr_subscr *vsub,
 			      enum trans_type type, uint8_t trans_id,
diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c
index 704e596..6eb5fee 100644
--- a/src/libmsc/gsm_04_08_cc.c
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -500,6 +500,15 @@
 	memset(&setup, 0, sizeof(struct gsm_mncc));
 	setup.callref = trans->callref;
 
+	/* New Global Call Reference */
+	if (!trans->cc.lcls) {
+		trans->cc.lcls = trans_lcls_compose(trans, true);
+	}
+
+	/* Pass the LCLS GCR on to the MT call leg via MNCC */
+	if (trans->cc.lcls)
+		setup.gcr = trans->cc.lcls->gcr;
+
 	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
 	/* emergency setup is identified by msg_type */
 	if (msg_type == GSM48_MT_CC_EMERG_SETUP) {
@@ -1969,6 +1978,16 @@
 		log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
 	}
 
+	/* Get the GCR from the MO call leg (if any).
+	* First make room for the LCLS info, then insert the MO call leg's GCR. */
+	if (!trans->cc.lcls) {
+		trans->cc.lcls = trans_lcls_compose(trans, true);
+		if (trans->cc.lcls) {
+			trans->cc.lcls->gcr = trans->cc.msg.gcr;
+			trans->cc.lcls->gcr_available = true;
+		}
+	}
+
 	LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(msg->msg_type));
 
 	gsm48_start_guard_timer(trans);
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index daa5bc7..9675734 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -549,6 +549,7 @@
 			.osmux_cid = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local_osmux_cid,
 			.call_id_present = true,
 			.call_id = cc_trans->callref,
+			.lcls = cc_trans->cc.lcls,
 		},
 	};
 	if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) {
@@ -1484,6 +1485,13 @@
 		rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_FAILURE);
 		break;
 
+	case RAN_MSG_LCLS_STATUS:
+		/* The BSS sends us LCLS_STATUS. We do nothing for now, but it is not an error. */
+		LOG_MSC_A(msc_a, LOGL_DEBUG, "LCLS_STATUS (%s) received from MSC-I\n",
+			  gsm0808_lcls_status_name(msg->lcls_status.status));
+		rc = 0;
+		break;
+
 	default:
 		LOG_MSC_A(msc_a, LOGL_ERROR, "Message from MSC-I not implemented: %s\n", ran_msg_type_name(msg->msg_type));
 		rc = -ENOTSUP;
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 79b4daa..ed119f1 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -498,6 +498,22 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_msc_lcls_disable, cfg_msc_lcls_disable_cmd,
+      "lcls-disable",
+      "Globally disable LCLS (Local Call Local Switch) for all calls on this MSC.\n")
+{
+	gsmnet->lcls_disable = 1;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_no_lcls_disable, cfg_msc_no_lcls_disable_cmd,
+      "no lcls-disable",
+      NO_STR "Globally disable LCLS (Local Call Local Switch) for all calls on this MSC.\n")
+{
+	gsmnet->lcls_disable = 0;
+	return CMD_SUCCESS;
+}
+
 DEFUN(cfg_msc_cs7_instance_a,
       cfg_msc_cs7_instance_a_cmd,
       "cs7-instance-a <0-15>",
@@ -763,6 +779,8 @@
 		gsmnet->ncss_guard_timeout, VTY_NEWLINE);
 	vty_out(vty, " %sassign-tmsi%s",
 		gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
+	vty_out(vty, " %slcls-disable%s",
+		gsmnet->lcls_disable? "" : "no ", VTY_NEWLINE);
 
 	vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
 		VTY_NEWLINE);
@@ -2082,6 +2100,8 @@
 	install_node(&msc_node, config_write_msc);
 	install_element(MSC_NODE, &cfg_sms_database_cmd);
 	install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
+	install_element(MSC_NODE, &cfg_msc_lcls_disable_cmd);
+	install_element(MSC_NODE, &cfg_msc_no_lcls_disable_cmd);
 	install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
 	install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
 	install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c
index 4cce289..da650bb 100644
--- a/src/libmsc/ran_msg_a.c
+++ b/src/libmsc/ran_msg_a.c
@@ -997,7 +997,8 @@
 	if(ac->call_id_present == true)
 		call_id = &ac->call_id;
 
-	msg = gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, use_scl, call_id);
+	msg = gsm0808_create_ass2(ac->channel_type, NULL, use_rtp_addr, use_scl, call_id,
+				  NULL, ac->lcls);
 	if (ac->osmux_present)
 		_gsm0808_assignment_extend_osmux(msg, ac->osmux_cid);
 	return msg;
diff --git a/src/libmsc/transaction.c b/src/libmsc/transaction.c
index 94712cc..799c496 100644
--- a/src/libmsc/transaction.c
+++ b/src/libmsc/transaction.c
@@ -110,6 +110,66 @@
 	return NULL;
 }
 
+struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac)
+{
+	if (!trans->net->a.sri->sccp) {
+		return NULL;
+	}
+	struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(trans->net->a.sri->sccp);
+	struct osmo_lcls *lcls;
+	uint8_t w = osmo_ss7_pc_width(&ss7->cfg.pc_fmt);
+
+	if (!trans) {
+		LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for unallocated transaction\n");
+		return NULL;
+	}
+
+	if (trans->net->lcls_disable) {
+		LOGP(DCC, LOGL_NOTICE, "LCLS disabled globally\n");
+		return NULL;
+	}
+
+	if (!trans->msc_a) {
+		LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for transaction without connection\n");
+		return NULL;
+	}
+
+	if (trans->msc_a->c.ran->type != OSMO_RAT_GERAN_A) {
+		LOGP(DCC, LOGL_ERROR, "LCLS: only A interface is supported at the moment\n");
+		return NULL;
+	}
+
+	lcls = talloc_zero(trans, struct osmo_lcls);
+	if (!lcls) {
+		LOGP(DCC, LOGL_ERROR, "LCLS: failed to allocate osmo_lcls\n");
+		return NULL;
+	}
+
+	LOGP(DCC, LOGL_INFO, "LCLS: using %u bits (%u bytes) for node ID\n", w, w / 8);
+
+	lcls->gcr.net_len = 3;
+	lcls->gcr.node = ss7->cfg.primary_pc;
+
+	/* net id from Q.1902.3 3-5 bytes, this function gives 3 bytes exactly */
+	osmo_plmn_to_bcd(lcls->gcr.net, &trans->net->plmn);
+
+	osmo_store32be(trans->callref, lcls->gcr.cr);
+	osmo_store16be(use_lac ? trans->msc_a->via_cell.lai.lac : trans->msc_a->via_cell.cell_identity, lcls->gcr.cr + 3);
+
+	LOGP(DCC, LOGL_INFO, "LCLS: allocated %s-based CR-ID %s\n", use_lac ? "LAC" : "CI",
+	     osmo_hexdump(lcls->gcr.cr, 5));
+
+	lcls->config = GSM0808_LCLS_CFG_BOTH_WAY;
+	lcls->control = GSM0808_LCLS_CSC_CONNECT;
+	lcls->corr_needed = true;
+	lcls->gcr_available = true;
+
+	LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_lcls_dump(lcls));
+	LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_gcr_dump(lcls));
+
+	return lcls;
+}
+
 static const char *trans_vsub_use(enum trans_type type)
 {
 	return get_value_string_or_null(trans_type_names, type) ? : "trans-type-unknown";
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
index fcca101..ac81532 100644
--- a/src/osmo-msc/msc_main.c
+++ b/src/osmo-msc/msc_main.c
@@ -258,6 +258,7 @@
 
 	mgcp_client_conf_init(&net->mgw.conf);
 	net->call_waiting = true;
+	net->lcls_disable = 1;
 
 	net->mgw.tdefs = g_mgw_tdefs;
 	osmo_tdefs_reset(net->mgw.tdefs);
diff --git a/tests/mncc/mncc_test.ok b/tests/mncc/mncc_test.ok
index 9334706..7cb1201 100644
--- a/tests/mncc/mncc_test.ok
+++ b/tests/mncc/mncc_test.ok
@@ -1,15 +1,15 @@
 test_sdp_termination()
 
 struct gsm_mncc:
-empty SDP: len=1860 sdplen=1026 sdp="\0" rc=0
-empty SDP, shortest possible: len=835 sdplen=1 sdp="\0" rc=0
-empty SDP, zero len: len=834 sdplen=0 sdp=- rc=-22
-terminated SDP str: len=1860 sdplen=1026 sdp="Privacy is a desirable marketing option\0" rc=0
-terminated SDP str, shortest possible: len=874 sdplen=40 sdp="Privacy is a desirable marketing option\0" rc=0
-terminated SDP str, but len excludes nul: len=873 sdplen=39 sdp="Privacy is a desirable marketing option" rc=-22
-terminated SDP str, but len too short: len=857 sdplen=23 sdp="Privacy is a desirable " rc=-22
-len way too short: len=10 sdplen=-824 sdp=- rc=-22
-len zero: len=0 sdplen=-834 sdp=- rc=-22
+empty SDP: len=1872 sdplen=1024 sdp="\0" rc=0
+empty SDP, shortest possible: len=849 sdplen=1 sdp="\0" rc=0
+empty SDP, zero len: len=848 sdplen=0 sdp=- rc=-22
+terminated SDP str: len=1872 sdplen=1024 sdp="Privacy is a desirable marketing option\0" rc=0
+terminated SDP str, shortest possible: len=888 sdplen=40 sdp="Privacy is a desirable marketing option\0" rc=0
+terminated SDP str, but len excludes nul: len=887 sdplen=39 sdp="Privacy is a desirable marketing option" rc=-22
+terminated SDP str, but len too short: len=871 sdplen=23 sdp="Privacy is a desirable " rc=-22
+len way too short: len=10 sdplen=-838 sdp=- rc=-22
+len zero: len=0 sdplen=-848 sdp=- rc=-22
 
 struct gsm_mncc_rtp:
 empty SDP: len=1168 sdplen=1024 sdp="\0" rc=0
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index f956a12..70f77f8 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -48,6 +48,7 @@
 ...
   sms-database PATH
   assign-tmsi
+  lcls disable <0-1>
   mncc internal
   mncc external MNCC_SOCKET_PATH
   mncc guard-timeout <0-255>

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-msc/+/24236
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Change-Id: I705c860e51637b4537cad65a330ecbaaca96dd5b
Gerrit-Change-Number: 24236
Gerrit-PatchSet: 1
Gerrit-Owner: keith <keith at rhizomatica.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210516/e8e307e9/attachment.htm>


More information about the gerrit-log mailing list