[PATCH] libosmo-sccp[master]: WIP: Add IPA/SCCPlite stacking

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

Harald Welte gerrit-no-reply at lists.osmocom.org
Sun Apr 9 19:28:48 UTC 2017


Review at  https://gerrit.osmocom.org/2282

WIP: Add IPA/SCCPlite stacking

Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56
---
M include/osmocom/sigtran/osmo_ss7.h
M src/osmo_ss7.c
M src/sccp_scrc.c
3 files changed, 134 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/82/2282/1

diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index 2d5eba9..e33a9ad 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -254,6 +254,7 @@
 	OSMO_SS7_ASP_PROT_NONE,
 	OSMO_SS7_ASP_PROT_SUA,
 	OSMO_SS7_ASP_PROT_M3UA,
+	OSMO_SS7_ASP_PROT_IPA,
 	_NUM_OSMO_SS7_ASP_PROT
 };
 
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index e55d55c..f9770c7 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -41,6 +41,7 @@
 #include <osmocom/core/socket.h>
 
 #include <osmocom/netif/stream.h>
+#include <osmocom/netif/ipa.h>
 
 #include "sccp_internal.h"
 #include "xua_internal.h"
@@ -68,11 +69,24 @@
 	{ OSMO_SS7_ASP_PROT_NONE,	"none" },
 	{ OSMO_SS7_ASP_PROT_SUA,	"sua" },
 	{ OSMO_SS7_ASP_PROT_M3UA,	"m3ua" },
+	{ OSMO_SS7_ASP_PROT_IPA,	"ipa" },
 	{ 0, NULL }
 };
 
 #define LOGSS7(inst, level, fmt, args ...)	\
 	LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args)
+
+static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto)
+{
+	switch (proto) {
+	case OSMO_SS7_ASP_PROT_IPA:
+		return IPPROTO_TCP;
+	case OSMO_SS7_ASP_PROT_SUA:
+	case OSMO_SS7_ASP_PROT_M3UA:
+	default:
+		return IPPROTO_SCTP;
+	}
+}
 
 int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst)
 {
@@ -786,7 +800,8 @@
 		as->cfg.proto = proto;
 		as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE;
 		as->cfg.recovery_timeout_msec = 2000;
-		as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
+		if (proto != OSMO_SS7_ASP_PROT_IPA)
+			as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
 		llist_add_tail(&as->list, &inst->as_list);
 	}
 
@@ -1020,6 +1035,7 @@
 }
 
 static int xua_cli_read_cb(struct osmo_stream_cli *conn);
+static int ipa_cli_read_cb(struct osmo_stream_cli *conn);
 static int xua_cli_connect_cb(struct osmo_stream_cli *cli);
 
 int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp)
@@ -1049,10 +1065,13 @@
 		osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port);
 		osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host);
 		osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port);
-		osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP);
+		osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto));
 		osmo_stream_cli_set_reconnect_timeout(asp->client, 5);
 		osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb);
-		osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb);
+		if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA)
+			osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb);
+		else
+			osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb);
 		osmo_stream_cli_set_data(asp->client, asp);
 		rc = osmo_stream_cli_open2(asp->client, 1);
 		if (rc < 0) {
@@ -1079,7 +1098,8 @@
 	/* (re)start the ASP FSM */
 	if (asp->fi)
 		osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL);
-	asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG);
+	if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA)
+		asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG);
 
 	return 0;
 }
@@ -1162,6 +1182,64 @@
 				notif->sn_header.sn_type));
 		break;
 	}
+}
+
+static int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg)
+{
+	struct osmo_mtp_prim *omp;
+
+	/* FIXME: pull the IPA header */
+
+	/* Generate an MTP-TRANSFER.ind and hand it into the MTP core
+	 * so it can dispatch it to SCCP */
+	omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp));
+	osmo_prim_init(&omp->oph, MTP_SAP_USER,
+			OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION, msg);
+	omp->u.transfer.opc = 0;
+	omp->u.transfer.dpc = 0;
+	omp->u.transfer.sio = MTP_SI_SCCP;
+	omp->u.transfer.sls = 0;
+
+	return osmo_ss7_mtp_to_user(asp->inst, omp);
+}
+
+/* netif code tells us we can read something from the socket */
+static int ipa_srv_conn_cb(struct osmo_stream_srv *conn)
+{
+	struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn);
+	struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn);
+	struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx");
+	int rc;
+
+	if (!msg)
+		return -ENOMEM;
+
+	/* read xUA message from socket and process it */
+	rc = osmo_stream_srv_recv(conn, msg);
+	LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): recvmsg() returned %d\n",
+		__func__, rc);
+	if (rc < 0) {
+		osmo_stream_srv_destroy(conn);
+		goto out;
+	} else if (rc == 0) {
+		osmo_stream_srv_destroy(conn);
+		goto out;
+	}
+	if (osmo_ipa_process_msg(msg) < 0) {
+		LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n");
+		osmo_stream_srv_destroy(conn);
+		goto out;
+	}
+	msg->dst = asp;
+
+	/* Handle IPA PING, PONG and ID_ACK messages */
+	if (osmo_ipa_rcvmsg_base(msg, ofd, 1))
+		return 0;
+
+	rc = ipa_rx_msg(asp, msg);
+out:
+	msgb_free(msg);
+	return rc;
 }
 
 /* netif code tells us we can read something from the socket */
@@ -1251,6 +1329,40 @@
 	}
 
 	return 0;
+}
+
+/* read call-back for IPA/SCCPlite socket */
+static int ipa_cli_read_cb(struct osmo_stream_cli *conn)
+{
+	struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn);
+	struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn);
+	struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "IPA Client Rx");
+	int rc;
+
+	if (!msg)
+		return -ENOMEM;
+
+	rc = osmo_stream_cli_recv(conn, msg);
+	if (rc <= 0) {
+		LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot receive message\n");
+		osmo_stream_cli_reconnect(conn);
+		goto out;
+	}
+	if (osmo_ipa_process_msg(msg) < 0) {
+		LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n");
+		osmo_stream_cli_reconnect(conn);
+		goto out;
+	}
+
+	/* Handle IPA PING, PONG and ID_ACK messages */
+	if (osmo_ipa_rcvmsg_base(msg, ofd, 0))
+		return 0;
+
+	msg->dst = asp;
+	rc = ipa_rx_msg(asp, msg);
+out:
+	msgb_free(msg);
+	return rc;
 }
 
 static int xua_cli_read_cb(struct osmo_stream_cli *conn)
@@ -1345,9 +1457,15 @@
 	LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n",
 		sock_name);
 
-	srv = osmo_stream_srv_create(oxs, link, fd,
-				     xua_srv_conn_cb,
-				     xua_srv_conn_closed_cb, NULL);
+	if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) {
+		srv = osmo_stream_srv_create(oxs, link, fd,
+					     ipa_srv_conn_cb,
+					     xua_srv_conn_closed_cb, NULL);
+	} else {
+		srv = osmo_stream_srv_create(oxs, link, fd,
+					     xua_srv_conn_cb,
+					     xua_srv_conn_closed_cb, NULL);
+	}
 	if (!srv) {
 		LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server "
 		     "for SCTP connection\n", sock_name);
@@ -1413,6 +1531,10 @@
 		break;
 	case OSMO_SS7_ASP_PROT_M3UA:
 		msgb_sctp_ppid(msg) = M3UA_PPID;
+		break;
+	case OSMO_SS7_ASP_PROT_IPA:
+		/* do we really want to do this here? */
+		osmo_ipa_msg_push_header(msg, FIXME);
 		break;
 	default:
 		OSMO_ASSERT(0);
@@ -1489,7 +1611,7 @@
 
 	osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host);
 	osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port);
-	osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP);
+	osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto));
 
 	rc = osmo_stream_srv_link_open(oxs->server);
 	if (rc < 0) {
diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c
index f9df075..80c8126 100644
--- a/src/sccp_scrc.c
+++ b/src/sccp_scrc.c
@@ -142,6 +142,7 @@
 		case OSMO_SS7_ASP_PROT_SUA:
 			return sua_tx_xua_as(as, xua);
 		case OSMO_SS7_ASP_PROT_M3UA:
+		case OSMO_SS7_ASP_PROT_IPA:
 			return sua2sccp_tx_m3ua(inst, xua);
 		default:
 			LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for "
@@ -295,7 +296,8 @@
 		       const struct osmo_sccp_addr *called)
 {
 	struct osmo_sccp_user *scu;
-
+	/* it is not really clear that called->pc will be set to
+	 * anything here, in the case of a SSN-only CalledAddr */
 	scu = sccp_user_find(inst, called->ssn, called->pc);
 
 	/* Is subsystem equipped? */

-- 
To view, visit https://gerrit.osmocom.org/2282
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56
Gerrit-PatchSet: 1
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>



More information about the gerrit-log mailing list