Change in osmo-pcu[master]: Use the new NS2 lib

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

lynxis lazus gerrit-no-reply at lists.osmocom.org
Thu Sep 24 03:16:41 UTC 2020


lynxis lazus has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-pcu/+/20271 )


Change subject: Use the new NS2 lib
......................................................................

Use the new NS2 lib

Depends: Id7edb8feb96436ba170383fc62d43ceb16955d53 (libosmocore)
Change-Id: Ib389925cf5c9f18951af6242c31ea70476218e9a
---
M src/bts.h
M src/gprs_bssgp_pcu.cpp
M src/gprs_bssgp_pcu.h
M src/osmobts_sock.cpp
M src/pcu_l1_if.cpp
M src/pcu_main.cpp
M src/pcu_vty.c
M tests/emu/pcu_emu.cpp
M tests/tbf/TbfTest.cpp
9 files changed, 249 insertions(+), 188 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/71/20271/1

diff --git a/src/bts.h b/src/bts.h
index 5a1b162..e930463 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -174,6 +174,11 @@
 	 * more than one message, because they get sent so rarely. */
 	struct msgb *app_info;
 	uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */
+
+	struct gprs_ns2_inst *nsi;
+	/* main nsei */
+	struct gprs_ns2_nse *nse;
+	uint16_t nsei;
 };
 
 enum {
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index d008d02..8383afd 100644
--- a/src/gprs_bssgp_pcu.cpp
+++ b/src/gprs_bssgp_pcu.cpp
@@ -30,6 +30,7 @@
 
 extern "C" {
 	#include <osmocom/gsm/protocol/gsm_23_003.h>
+	#include <osmocom/gprs/protocol/gsm_08_16.h>
 	#include <osmocom/core/utils.h>
 	#include "coding_scheme.h"
 }
@@ -51,7 +52,6 @@
 extern bool spoof_mnc_3_digits;
 
 static void bvc_timeout(void *_priv);
-static int gprs_ns_reconnect(struct gprs_nsvc *nsvc);
 
 static int parse_ra_cap(struct tlv_parsed *tp, MS_Radio_Access_capability_t *rac)
 {
@@ -549,75 +549,91 @@
 	return 0;
 }
 
-int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci)
+void gprs_ns_prim_status_cb(struct osmo_gprs_ns2_prim *nsp)
 {
-	int rc = 0;
-	switch (event) {
-	case GPRS_NS_EVT_UNIT_DATA:
-		/* hand the message into the BSSGP implementation */
-		rc = gprs_bssgp_pcu_rcvmsg(msg);
+	switch (nsp->u.status.cause) {
+	case NS_AFF_CAUSE_SNS_CONFIGURED:
+		LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d SNS configured.\n", nsp->nsei);
 		break;
-	default:
-		LOGP(DPCU, LOGL_NOTICE, "RLCMAC: Unknown event %u from NS\n", event);
-		rc = -EIO;
-		break;
-	}
-	return rc;
-}
-
-
-static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
-	void *handler_data, void *signal_data)
-{
-	struct ns_signal_data *nssd;
-
-	if (subsys != SS_L_NS)
-		return -EINVAL;
-
-	nssd = (struct ns_signal_data *)signal_data;
-	if (signal != S_SNS_CONFIGURED &&  nssd->nsvc != the_pcu.nsvc) {
-		LOGP(DPCU, LOGL_ERROR, "Signal received of unknown NSVC\n");
-		return -EINVAL;
-	}
-
-	switch (signal) {
-	case S_SNS_CONFIGURED:
-		the_pcu.bvc_sig_reset = 0;
-		the_pcu.bvc_reset = 0;
-		/* There's no NS-RESET / NS-UNBLOCK procedure on IP SNS based NS-VCs */
-		the_pcu.nsvc_unblocked = 1;
-		LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n", the_pcu.nsvc->nsvci);
-		bvc_timeout(NULL);
-		break;
-	case S_NS_UNBLOCK:
+	case NS_AFF_CAUSE_RECOVERY:
+		LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became available\n", nsp->nsei);
 		if (!the_pcu.nsvc_unblocked) {
-			the_pcu.nsvc_unblocked = 1;
-			LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n",
-				the_pcu.nsvc->nsvci);
 			the_pcu.bvc_sig_reset = 0;
 			the_pcu.bvc_reset = 0;
-			the_pcu.bvc_unblocked = 0;
+			the_pcu.nsvc_unblocked = 1;
 			bvc_timeout(NULL);
 		}
 		break;
-	case S_NS_BLOCK:
+	case NS_AFF_CAUSE_FAILURE:
+		LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became unavailable\n", nsp->nsei);
 		if (the_pcu.nsvc_unblocked) {
 			the_pcu.nsvc_unblocked = 0;
 			osmo_timer_del(&the_pcu.bvc_timer);
 			the_pcu.bvc_sig_reset = 0;
 			the_pcu.bvc_reset = 0;
 			the_pcu.bvc_unblocked = 0;
-			LOGP(DPCU, LOGL_NOTICE, "NS-VC is blocked.\n");
 		}
 		break;
-	case S_NS_ALIVE_EXP:
-		LOGP(DPCU, LOGL_NOTICE, "Tns alive expired too often, "
-			"re-starting RESET procedure\n");
-		gprs_ns_reconnect(nssd->nsvc);
+	default:
+		LOGP(DPCU, LOGL_NOTICE,
+		     "NS: %s Unknown prim %d from NS\n",
+		     get_value_string(osmo_prim_op_names, nsp->oph.operation),
+		     nsp->oph.primitive);
+		break;
+	}
+}
+
+/* called by the ns layer */
+int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+	struct osmo_gprs_ns2_prim *nsp;
+	int rc = 0;
+
+	if (oph->sap != SAP_NS)
+		return 0;
+
+	nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);
+
+	if (oph->operation != PRIM_OP_INDICATION) {
+		LOGP(DPCU, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
+		     get_value_string(osmo_prim_op_names, oph->operation),
+		     oph->operation);
+		return 0;
+	}
+
+	switch (oph->primitive) {
+	case PRIM_NS_UNIT_DATA:
+		/* hand the message into the BSSGP implementation */
+		/* add required msg fields for Gb layer */
+		msgb_bssgph(oph->msg) = oph->msg->l3h;
+		msgb_bvci(oph->msg) = nsp->bvci;
+		msgb_nsei(oph->msg) = nsp->nsei;
+		rc = gprs_bssgp_pcu_rcvmsg(oph->msg);
+		break;
+	case PRIM_NS_STATUS:
+		gprs_ns_prim_status_cb(nsp);
+		break;
+	default:
+		LOGP(DPCU, LOGL_NOTICE,
+		     "NS: %s Unknown prim %d from NS\n",
+		     get_value_string(osmo_prim_op_names, oph->operation),
+		     oph->primitive);
 		break;
 	}
 
-	return 0;
+	return rc;
+}
+
+/* called by the bssgp layer to send NS PDUs */
+int gprs_bssgp_send_cb(void *ctx, struct msgb *msg)
+{
+	struct gprs_ns2_inst *nsi = (struct gprs_ns2_inst *) ctx;
+	struct osmo_gprs_ns2_prim nsp = {};
+	nsp.nsei = msgb_nsei(msg);
+	nsp.bvci = msgb_bvci(msg);
+	osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,
+			PRIM_OP_REQUEST, msg);
+	return gprs_ns2_recv_prim(nsi, &nsp.oph);
 }
 
 static unsigned count_pdch(const struct gprs_rlcmac_bts *bts)
@@ -904,77 +920,65 @@
 	osmo_timer_schedule(&the_pcu.bvc_timer, the_pcu.bts->fc_interval, 0);
 }
 
-static int gprs_ns_reconnect(struct gprs_nsvc *nsvc)
-{
-	struct gprs_nsvc *nsvc2;
 
-	if (nsvc != the_pcu.nsvc) {
-		LOGP(DBSSGP, LOGL_ERROR, "NSVC is invalid\n");
-		return -EBADF;
+int gprs_nsvc_create_and_connect(
+		struct gprs_rlcmac_bts *bts,
+		struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn,
+		uint16_t nsei, uint16_t nsvci)
+{
+	struct gprs_ns2_vc *nsvc;
+	struct gprs_ns2_vc_bind *bind;
+	int rc;
+
+	rc = gprs_ns2_ip_bind(bts->nsi, local, 0, &bind);
+	if (rc < 0) {
+		LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n");
+		gprs_ns2_free(bts->nsi);
+		return 1;
 	}
 
-	if (the_pcu.bts->gb_dialect_sns)
-		nsvc2 = gprs_ns_nsip_connect_sns(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
-	else
-		nsvc2 = gprs_ns_nsip_connect(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
-	if (!nsvc2) {
-		LOGP(DBSSGP, LOGL_ERROR, "Failed to reconnect NSVC\n");
-		return -EIO;
+	bts->nse = gprs_ns2_nse_by_nsei(bts->nsi, nsei);
+	if (!bts->nse)
+		bts->nse = gprs_ns2_create_nse(bts->nsi, nsei);
+
+	if (!bts->nse) {
+		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSE\n");
+		return 1;
+	}
+
+	bts->nsei = nsei;
+	if (bts->gb_dialect_sns) {
+		rc = gprs_ns2_ip_connect_sns(bind, sgsn, nsei);
+	} else {
+		nsvc = gprs_ns2_ip_connect2(bind, sgsn, nsei, nsvci);
+		if (!nsvc)
+			rc = -1;
+	}
+
+	if (rc) {
+		/* TODO: Could not connect */
+		return 1;
 	}
 
 	return 0;
 }
 
-/* create BSSGP/NS layer instances */
-struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts,
-	uint16_t local_port, uint32_t sgsn_ip,
-	uint16_t sgsn_port, uint16_t nsei, uint16_t nsvci, uint16_t bvci,
-	uint16_t mcc, uint16_t mnc, bool mnc_3_digits, uint16_t lac, uint16_t rac,
-	uint16_t cell_id)
+struct gprs_bssgp_pcu *gprs_bssgp_init(
+		struct gprs_rlcmac_bts *bts,
+		uint16_t nsei, uint16_t bvci,
+		uint16_t mcc, uint16_t mnc, bool mnc_3_digits,
+		uint16_t lac, uint16_t rac, uint16_t cell_id)
 {
-	struct sockaddr_in dest;
-	int rc;
 
 	/* if already created... return the current address */
 	if (the_pcu.bctx)
 		return &the_pcu;
 
 	the_pcu.bts = bts;
-
-	/* don't specify remote IP/port if SNS dialect is in use; Doing so would
-	 * issue a connect() on the socket, which prevents us to dynamically communicate
-	 * with any number of IP-SNS endpoints on the SGSN side */
-	if (!bts->gb_dialect_sns) {
-		bssgp_nsi->nsip.remote_port = sgsn_port;
-		bssgp_nsi->nsip.remote_ip = sgsn_ip;
-	}
-	bssgp_nsi->nsip.local_port = local_port;
-	rc = gprs_ns_nsip_listen(bssgp_nsi);
-	if (rc < 0) {
-		LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n");
-		gprs_ns_close(bssgp_nsi);
-		return NULL;
-	}
-
-	dest.sin_family = AF_INET;
-	dest.sin_port = htons(sgsn_port);
-	dest.sin_addr.s_addr = htonl(sgsn_ip);
-
-	if (bts->gb_dialect_sns)
-		the_pcu.nsvc = gprs_ns_nsip_connect_sns(bssgp_nsi, &dest, nsei, nsvci);
-	else
-		the_pcu.nsvc = gprs_ns_nsip_connect(bssgp_nsi, &dest, nsei, nsvci);
-	if (!the_pcu.nsvc) {
-		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSVCt\n");
-		gprs_ns_close(bssgp_nsi);
-		return NULL;
-	}
-
 	the_pcu.bctx = btsctx_alloc(bvci, nsei);
 	if (!the_pcu.bctx) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create BSSGP context\n");
-		the_pcu.nsvc = NULL;
-		gprs_ns_close(bssgp_nsi);
+		the_pcu.bts->nse = NULL;
 		return NULL;
 	}
 	the_pcu.bctx->ra_id.mcc = spoof_mcc ? : mcc;
@@ -989,37 +993,27 @@
 	the_pcu.bctx->ra_id.rac = rac;
 	the_pcu.bctx->cell_id = cell_id;
 
-	osmo_signal_register_handler(SS_L_NS, nsvc_signal_cb, NULL);
-
-	osmo_timer_setup(&the_pcu.bvc_timer, bvc_timeout, NULL);
+	osmo_timer_setup(&the_pcu.bvc_timer, bvc_timeout, bts);
 
 	return &the_pcu;
 }
 
-void gprs_bssgp_destroy(void)
+void gprs_bssgp_destroy(struct gprs_rlcmac_bts *bts)
 {
-	struct gprs_ns_inst *nsi = bssgp_nsi;
-	if (!nsi)
-		return;
-
-	bssgp_nsi = NULL;
-
 	osmo_timer_del(&the_pcu.bvc_timer);
 
-	osmo_signal_unregister_handler(SS_L_NS, nsvc_signal_cb, NULL);
-
-	the_pcu.nsvc = NULL;
-
 	/* FIXME: blocking... */
 	the_pcu.nsvc_unblocked = 0;
 	the_pcu.bvc_sig_reset = 0;
 	the_pcu.bvc_reset = 0;
 	the_pcu.bvc_unblocked = 0;
 
-	gprs_ns_destroy(nsi);
-
 	bssgp_bvc_ctx_free(the_pcu.bctx);
 	the_pcu.bctx = NULL;
+
+	gprs_ns2_free(bts->nsi);
+	bts->nsi = NULL;
+	bts->nse = NULL;
 }
 
 struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void)
diff --git a/src/gprs_bssgp_pcu.h b/src/gprs_bssgp_pcu.h
index 2ceef60..6341161 100644
--- a/src/gprs_bssgp_pcu.h
+++ b/src/gprs_bssgp_pcu.h
@@ -28,7 +28,7 @@
 #include <osmocom/core/logging.h>
 #include <osmocom/core/signal.h>
 #include <osmocom/core/application.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
 #include <osmocom/gprs/gprs_bssgp.h>
 #include <osmocom/gprs/gprs_bssgp_bss.h>
 #include <osmocom/gprs/gprs_msgb.h>
@@ -45,7 +45,6 @@
 #define IE_LLC_PDU 14
 
 struct gprs_bssgp_pcu {
-	struct gprs_nsvc *nsvc;
 	struct bssgp_bvc_ctx *bctx;
 
 	struct gprs_rlcmac_bts *bts;
@@ -76,16 +75,21 @@
 				struct tlv_parsed *tp);
 };
 
-struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts,
-		uint16_t local_port,
-		uint32_t sgsn_ip, uint16_t sgsn_port, uint16_t nsei,
-		uint16_t nsvci, uint16_t bvci, uint16_t mcc, uint16_t mnc, bool mnc_3_digits,
+struct gprs_bssgp_pcu *gprs_bssgp_init(
+		struct gprs_rlcmac_bts *bts,
+		uint16_t nsei, uint16_t bvci,
+		uint16_t mcc, uint16_t mnc, bool mnc_3_digits,
 		uint16_t lac, uint16_t rac, uint16_t cell_id);
 
-int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
-	       struct msgb *msg, uint16_t bvci);
+int gprs_nsvc_create_and_connect(
+		struct gprs_rlcmac_bts *bts,
+		struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn,
+		uint16_t nsei, uint16_t nsvci);
 
-void gprs_bssgp_destroy(void);
+int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
+int gprs_bssgp_send_cb(void *ctx, struct msgb *msg);
+
+void gprs_bssgp_destroy(struct gprs_rlcmac_bts *bts);
 
 struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void);
 
diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp
index 8d3d26f..c9beff0 100644
--- a/src/osmobts_sock.cpp
+++ b/src/osmobts_sock.cpp
@@ -121,7 +121,7 @@
 		gprs_rlcmac_tbf::free_all(&bts->trx[trx]);
 	}
 
-	gprs_bssgp_destroy();
+	gprs_bssgp_destroy(bts);
 	exit(0);
 }
 
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 535fb70..b58e2ff 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -36,6 +36,7 @@
 #include <osmocom/core/gsmtap_util.h>
 #include <osmocom/core/gsmtap.h>
 #include <osmocom/core/bitvec.h>
+#include <osmocom/core/sockaddr_str.h>
 #include <osmocom/core/logging.h>
 #include <osmocom/core/utils.h>
 #include <osmocom/gsm/l1sap.h>
@@ -491,8 +492,9 @@
 {
 	struct gprs_rlcmac_bts *bts = bts_main_data();
 	struct gprs_bssgp_pcu *pcu;
-	struct in_addr ia;
+	struct osmo_sockaddr local_sockaddr = {}, remote_sockaddr = {};
 	int rc = 0;
+	int good_nsvc = 0;
 	unsigned int trx_nr, ts_nr;
 	int i;
 
@@ -517,7 +519,7 @@
 			for (ts_nr = 0; ts_nr < ARRAY_SIZE(bts->trx[0].pdch); ts_nr++)
 				bts->trx[trx_nr].pdch[ts_nr].free_resources();
 		}
-		gprs_bssgp_destroy();
+		gprs_bssgp_destroy(bts);
 		exit(0);
 	}
 	LOGP(DL1IF, LOGL_INFO, "BTS available\n");
@@ -566,30 +568,65 @@
 	}
 	LOGP(DL1IF, LOGL_DEBUG, " initial_cs=%d\n", info_ind->initial_cs);
 	LOGP(DL1IF, LOGL_DEBUG, " initial_mcs=%d\n", info_ind->initial_mcs);
-	LOGP(DL1IF, LOGL_DEBUG, " nsvci=%d\n", info_ind->nsvci[0]);
-	LOGP(DL1IF, LOGL_DEBUG, " local_port=%d\n", info_ind->local_port[0]);
-	LOGP(DL1IF, LOGL_DEBUG, " remote_port=%d\n", info_ind->remote_port[0]);
-	ia.s_addr = info_ind->remote_ip[0].v4.s_addr;
-	LOGP(DL1IF, LOGL_DEBUG, " remote_ip=%s\n", inet_ntoa(ia));
 
-	switch (info_ind->address_type[0]) {
-	case PCU_IF_ADDR_TYPE_IPV4:
-		break;
-	case PCU_IF_ADDR_TYPE_IPV6:
-		LOGP(DL1IF, LOGL_ERROR, "This PCU does not support IPv6 NSVC!\n");
-		goto bssgp_failed;
-	default:
-		LOGP(DL1IF, LOGL_ERROR, "No IPv4 NSVC given!\n");
+	pcu = gprs_bssgp_init(
+			bts,
+			info_ind->nsei, info_ind->bvci,
+			info_ind->mcc, info_ind->mnc, info_ind->mnc_3_digits,
+			info_ind->lac, info_ind->rac, info_ind->cell_id);
+	if (!pcu) {
+		LOGP(DL1IF, LOGL_NOTICE, "Failed to init BSSGP\n");
 		goto bssgp_failed;
 	}
 
-	pcu = gprs_bssgp_create_and_connect(bts, info_ind->local_port[0],
-		ntohl(info_ind->remote_ip[0].v4.s_addr), info_ind->remote_port[0],
-		info_ind->nsei, info_ind->nsvci[0], info_ind->bvci,
-		info_ind->mcc, info_ind->mnc, info_ind->mnc_3_digits, info_ind->lac, info_ind->rac,
-		info_ind->cell_id);
-	if (!pcu) {
-		LOGP(DL1IF, LOGL_NOTICE, "SGSN is not available\n");
+	for (int i=0; i<2; i++) {
+		struct osmo_sockaddr_str sockstr;
+
+		switch (info_ind->address_type[i]) {
+		case IPPROTO_IPIP:
+			local_sockaddr.u.sin.sin_family = AF_INET;
+			local_sockaddr.u.sin.sin_addr.s_addr = INADDR_ANY;
+			local_sockaddr.u.sin.sin_port = htons(info_ind->local_port[i]);
+
+			remote_sockaddr.u.sin.sin_family = AF_INET;
+			remote_sockaddr.u.sin.sin_addr = info_ind->remote_ip[i].v4;
+			remote_sockaddr.u.sin.sin_port = htons(info_ind->remote_port[i]);
+			break;
+		case IPPROTO_IPV6:
+			local_sockaddr.u.sin6.sin6_family = AF_INET6;
+			local_sockaddr.u.sin6.sin6_addr = in6addr_any;
+			local_sockaddr.u.sin6.sin6_port = htons(info_ind->local_port[i]);
+
+			remote_sockaddr.u.sin6.sin6_family = AF_INET6;
+			remote_sockaddr.u.sin6.sin6_addr = info_ind->remote_ip[i].v6;
+			remote_sockaddr.u.sin6.sin6_port = htons(info_ind->remote_port[i]);
+			break;
+		default:
+			continue;
+		}
+
+		LOGP(DL1IF, LOGL_DEBUG, " NS%d nsvci=%d\n", i, info_ind->nsvci[i]);
+		LOGP(DL1IF, LOGL_DEBUG, " NS%d local_port=%d\n", i, info_ind->local_port[i]);
+		LOGP(DL1IF, LOGL_DEBUG, " NS%d remote_port=%d\n", i, info_ind->remote_port[i]);
+
+		if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote_sockaddr.u.sas))
+			strcpy(sockstr.ip, "invalid");
+
+		LOGP(DL1IF, LOGL_DEBUG, " NS%d remote_ip=%s\n", i, sockstr.ip);
+		rc = gprs_nsvc_create_and_connect(bts,
+						  &local_sockaddr, &remote_sockaddr,
+						  info_ind->nsei, info_ind->nsvci[i]);
+		if (rc) {
+			LOGP(DL1IF, LOGL_ERROR, "Failed to create NSVC connection to %s:%d!\n",
+			     sockstr.ip, sockstr.port);
+			continue;
+		}
+
+		good_nsvc++;
+	}
+
+	if (good_nsvc == 0) {
+		LOGP(DL1IF, LOGL_ERROR, "No NSVC available to connect to the SGSN!\n");
 		goto bssgp_failed;
 	}
 
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index c5ff3dc..6616e11 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -38,7 +38,7 @@
 #include "pcu_vty.h"
 #include "coding_scheme.h"
 #include <osmocom/gprs/gprs_bssgp.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/command.h>
 #include <osmocom/vty/vty.h>
@@ -267,7 +267,6 @@
 
 	osmo_stats_init(tall_pcu_ctx);
 	rate_ctr_init(tall_pcu_ctx);
-	gprs_ns_set_log_ss(DNS);
 	bssgp_set_log_ss(DBSSGP);
 
 	pcu_vty_info.tall_ctx = tall_pcu_ctx;
@@ -289,12 +288,13 @@
 	else
 		fprintf(stderr, "Failed to initialize GSMTAP for %s\n", gsmtap_addr);
 
-	bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
-	if (!bssgp_nsi) {
+	bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		exit(1);
 	}
-	gprs_ns_vty_init(bssgp_nsi);
+	bssgp_set_bssgp_callback(gprs_bssgp_send_cb, bts->nsi);
+	gprs_ns2_vty_init(bts->nsi);
 
 	rc = vty_read_config_file(config_file, NULL);
 	if (rc < 0 && config_given) {
@@ -306,6 +306,8 @@
 		fprintf(stderr, "No config file: '%s' Using default config.\n",
 			config_file);
 
+	gprs_ns2_vty_create();
+
 	rc = telnet_init_dynif(tall_pcu_ctx, NULL, vty_get_bind_addr(),
 			       OSMO_VTY_PORT_PCU);
 	if (rc < 0) {
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index 0756136..010f98d 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -13,6 +13,7 @@
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/rate_ctr.h>
 #include <osmocom/pcu/pcuif_proto.h>
+#include <osmocom/gprs/gprs_ns2.h>
 #include "pcu_vty.h"
 #include "gprs_rlcmac.h"
 #include <pdch.h>
@@ -1096,10 +1097,13 @@
 {
 	struct gprs_rlcmac_bts *bts = bts_main_data();
 
-	if (!strcmp(argv[0], "ip-sns"))
+	if (!strcmp(argv[0], "ip-sns")) {
 		bts->gb_dialect_sns = true;
-	else
+		gprs_ns2_vty_force_vc_mode(true, NS2_VC_MODE_ALIVE, "gb-dialect is ip-sns");
+	} else {
 		bts->gb_dialect_sns = false;
+		gprs_ns2_vty_force_vc_mode(false, 0, NULL);
+	}
 
 	return CMD_SUCCESS;
 }
diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp
index 7f99355..9c3a212 100644
--- a/tests/emu/pcu_emu.cpp
+++ b/tests/emu/pcu_emu.cpp
@@ -93,15 +93,28 @@
 			uint32_t sgsn_ip, uint16_t sgsn_port)
 {
 	struct gprs_bssgp_pcu *pcu;
+	struct osmo_sockaddr local, remote;
 
-	pcu = gprs_bssgp_create_and_connect(bts, 0, sgsn_ip, sgsn_port,
-					20, 20, 20, 901, 99, false, 1, 0, 0);
+	local.u.sin.sin_family = AF_INET;
+	local.u.sin.sin_addr.s_addr = 0;
+	local.u.sin.sin_port = 0;
+
+	remote.u.sin.sin_family = AF_INET;
+	remote.u.sin.sin_addr.s_addr = htonl(sgsn_ip);
+	remote.u.sin.sin_port = htons(sgsn_port);
+
+	pcu = gprs_bssgp_init(bts, 20, 20, 901, 99, false, 1, 0, 0);
+	gprs_nsvc_create_and_connect(bts, &local, &remote,
+				     20, 20);
+
 	pcu->on_unblock_ack = bvci_unblocked;
 	pcu->on_dl_unit_data = bssgp_data;
 }
 
 int main(int argc, char **argv)
 {
+	struct gprs_rlcmac_bts *bts = bts_main_data();
+
 	tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile Emu-PCU context");
 	if (!tall_pcu_ctx)
 		abort();
@@ -109,8 +122,8 @@
 	msgb_talloc_ctx_init(tall_pcu_ctx, 0);
 	osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
 
-	bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
-	if (!bssgp_nsi) {
+	bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, &gprs_ns_prim_cb, NULL);
+	if (!bts->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
@@ -121,7 +134,8 @@
 	current_test = 0;
 
 	init_main_bts();
-	create_and_connect_bssgp(bts_main_data(), INADDR_LOOPBACK, 23000);
+	bssgp_set_bssgp_callback(gprs_bssgp_send_cb, bts->nsi);
+	create_and_connect_bssgp(bts, INADDR_LOOPBACK, 23000);
 	
 	for (;;)
 		osmo_select_main(0);
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index b16c089..15a79d0 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -470,15 +470,15 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
-	if (!bssgp_nsi) {
+	bts = the_bts.bts_data();
+	bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	bts = the_bts.bts_data();
 	setup_bts(&the_bts, ts_no);
-	gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
+	gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
 
 	for (i = 0; i < 1024; i++) {
 		uint32_t tlli = 0xc0000000 + i;
@@ -497,7 +497,7 @@
 	OSMO_ASSERT(rc == -EBUSY);
 	fprintf(stderr, "=== end %s ===\n", __func__);
 
-	gprs_bssgp_destroy();
+	gprs_bssgp_destroy(bts);
 }
 
 static void test_tbf_dl_llc_loss()
@@ -514,20 +514,20 @@
 
 	uint8_t buf[19];
 
-	bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
-	if (!bssgp_nsi) {
+	bts = the_bts.bts_data();
+	bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bts = the_bts.bts_data();
 	setup_bts(&the_bts, ts_no);
 	/* keep the MS object 10 seconds */
 	OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2030, 10, OSMO_TDEF_S) == 0);
 
-	gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 2234, 2234, 2234, 1, 1, false, 0, 0, 0);
+	gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
 
 	/* Handle LLC frame 1 */
 	memset(buf, 1, sizeof(buf));
@@ -582,7 +582,7 @@
 
 	fprintf(stderr, "=== end %s ===\n", __func__);
 
-	gprs_bssgp_destroy();
+	gprs_bssgp_destroy(bts);
 }
 
 static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
@@ -2165,19 +2165,19 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
-	if (!bssgp_nsi) {
+	bts = the_bts.bts_data();
+	bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	bts = the_bts.bts_data();
 	setup_bts(&the_bts, ts_no);
 
 	/* EGPRS-only */
 	bts->egprs_enabled = 1;
 
-	gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 3234, 3234, 3234, 1, 1, false, 0, 0, 0);
+	gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
 
 	/* Does not support EGPRS */
 	rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
@@ -2186,12 +2186,13 @@
 	OSMO_ASSERT(rc == -EBUSY);
 	fprintf(stderr, "=== end %s ===\n", __func__);
 
-	gprs_bssgp_destroy();
+	gprs_bssgp_destroy(bts);
 }
 
 static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
 			    bool free, bool end)
 {
+	gprs_rlcmac_bts *bts = dl_tbf->bts->bts_data();
 	if (!dl_tbf) {
 		fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
 		return;
@@ -2213,7 +2214,7 @@
 
 	if (end) {
 		fprintf(stderr, "=== end %s ===\n", test);
-		gprs_bssgp_destroy();
+		gprs_bssgp_destroy(bts);
 	}
 }
 
@@ -2228,13 +2229,13 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
-	if (!bssgp_nsi) {
+	bts = the_bts.bts_data();
+	bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	bts = the_bts.bts_data();
 	setup_bts(&the_bts, ts_no);
 
 	bts->ws_base = 128;
@@ -2245,7 +2246,7 @@
 	bts->trx[0].pdch[4].enable();
 	bts->trx[0].pdch[5].enable();
 
-	gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 4234, 4234, 4234, 1, 1, false, 0, 0, 0);
+	gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
 
 	/* Does no support EGPRS */
 	ms = the_bts.ms_alloc(ms_class, 0);
@@ -2274,13 +2275,13 @@
 
 	fprintf(stderr, "=== start %s ===\n", __func__);
 
-	bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
-	if (!bssgp_nsi) {
+	bts = the_bts.bts_data();
+	bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
+	if (!bts->nsi) {
 		LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
 		abort();
 	}
 
-	bts = the_bts.bts_data();
 	setup_bts(&the_bts, ts_no);
 
 	bts->ws_base = 128;
@@ -2291,7 +2292,7 @@
 	bts->trx[0].pdch[4].enable();
 	bts->trx[0].pdch[5].enable();
 
-	gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 5234, 5234, 5234, 1, 1, false, 0, 0, 0);
+	gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
 
 	/* EGPRS-only */
 	bts->egprs_enabled = 1;

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

Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: Ib389925cf5c9f18951af6242c31ea70476218e9a
Gerrit-Change-Number: 20271
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200924/d6f45f92/attachment.htm>


More information about the gerrit-log mailing list