ns: Reconnect NSVC after timeout

Currently the signal S_NS_ALIVE_EXP emitted by the NS layer if the
alive check has timed out too often is ignored. This prevents the PCU
from reconnecting to the SGSN if it has not been accessible for some
time.

This commit modifies nsvc_signal_cb to reset the NSCV if
S_NS_ALIVE_EXP is sent, so that the PCU continues to send NS RESET
message if that happened.

Sponsored-by: On-Waves ehf
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index 7601b21..7f50e17 100644
--- a/src/gprs_bssgp_pcu.cpp
+++ b/src/gprs_bssgp_pcu.cpp
@@ -503,6 +503,11 @@
 			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);
+		break;
 	}
 
 	return 0;
@@ -723,6 +728,31 @@
 	osmo_timer_schedule(&the_pcu.bvc_timer, the_pcu.bts->fc_interval, 0);
 }
 
+int gprs_ns_reconnect(struct gprs_nsvc *nsvc)
+{
+	struct gprs_nsvc *nsvc2;
+
+	if (!bssgp_nsi) {
+		LOGP(DBSSGP, LOGL_ERROR, "NS instance does not exist\n");
+		return -EINVAL;
+	}
+
+	if (nsvc != the_pcu.nsvc) {
+		LOGP(DBSSGP, LOGL_ERROR, "NSVC is invalid\n");
+		return -EBADF;
+	}
+
+	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;
+	}
+
+	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,