Cleanup of BSSGP code.

The hack for resetting BSSGP instance is removed and now performed
whenever the NS state changes to UNBLOCKED.

The BSSGP instance is now created only once, as it should be.

Received STATUS messages are ignored as they should be.

The creation and destruction of BSSGP/NS instances is now handled by
layer 1 interface alone.
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index c08cc8f..4921b21 100644
--- a/src/gprs_bssgp_pcu.cpp
+++ b/src/gprs_bssgp_pcu.cpp
@@ -23,7 +23,7 @@
 
 struct sgsn_instance *sgsn;
 void *tall_bsc_ctx;
-struct bssgp_bvc_ctx *bctx = btsctx_alloc(BVCI, NSEI);
+struct bssgp_bvc_ctx *bctx = NULL;
 struct gprs_nsvc *nsvc = NULL;
 extern uint16_t spoof_mcc, spoof_mnc;
 
@@ -225,6 +225,13 @@
 	uint16_t ns_bvci = msgb_bvci(msg);
 	int data_len;
 	int rc = 0;
+	struct bssgp_bvc_ctx *bctx;
+
+	if (pdu_type == BSSGP_PDUT_STATUS) {
+		LOGP(DBSSGP, LOGL_NOTICE, "NSEI=%u/BVCI=%u received STATUS\n",
+			msgb_nsei(msg), ns_bvci);
+		return 0;
+	}
 
 	/* Identifiers from DOWN: NSEI, BVCI (both in msg->cb) */
 
@@ -243,12 +250,6 @@
 	/* look-up or create the BTS context for this BVC */
 	bctx = btsctx_by_bvci_nsei(ns_bvci, msgb_nsei(msg));
 
-	/* Only a RESET PDU can create a new BVC context */
-	if (!bctx)
-	{
-		bctx = btsctx_alloc(ns_bvci, msgb_nsei(msg));
-	}
-
 	if (!bctx && pdu_type != BSSGP_PDUT_BVC_RESET_ACK)
 	{
 		LOGP(DBSSGP, LOGL_NOTICE, "NSEI=%u/BVCI=%u Rejecting PDU "
diff --git a/src/gprs_bssgp_pcu.h b/src/gprs_bssgp_pcu.h
index 30b1ff6..7d5f376 100644
--- a/src/gprs_bssgp_pcu.h
+++ b/src/gprs_bssgp_pcu.h
@@ -39,23 +39,10 @@
 }
 #include <gprs_debug.h>
 
-#define BVCI 7
-#define NSEI 3
-
 #define QOS_PROFILE 0
 #define BSSGP_HDR_LEN 53
 #define NS_HDR_LEN 4
-#define MAX_LEN_PDU 60
 #define IE_LLC_PDU 14
-#define BLOCK_DATA_LEN 20
-#define BLOCK_LEN 23
-
-#define CELL_ID 0
-#define MNC 2
-#define MCC 262
-#define PCU_LAC 1
-#define PCU_RAC 0
-
 
 extern struct bssgp_bvc_ctx *bctx;
 
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp
index bfed57d..b68af3f 100644
--- a/src/gprs_rlcmac.cpp
+++ b/src/gprs_rlcmac.cpp
@@ -590,27 +590,25 @@
 }
 
 /* Send Uplink unit-data to SGSN. */
-void gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf)
+int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf)
 {
 	const uint8_t qos_profile = QOS_PROFILE;
 	struct msgb *llc_pdu;
 	unsigned msg_len = NS_HDR_LEN + BSSGP_HDR_LEN + tbf->llc_index;
 
 	LOGP(DBSSGP, LOGL_NOTICE, "TX: [PCU -> SGSN ] TFI: %u TLLI: 0x%08x DataLen: %u\n", tbf->tfi, tbf->tlli, tbf->llc_index);
+	if (!bctx) {
+		LOGP(DBSSGP, LOGL_ERROR, "No bctx\n");
+		return -EIO;
+	}
 	//LOGP(DBSSGP, LOGL_NOTICE, " Data = ");
 	//for (unsigned i = 0; i < tbf->llc_index; i++)
 	//	LOGPC(DBSSGP, LOGL_NOTICE, "%02x ", tbf->llc_frame[i]);
 	
-	bctx->cell_id = CELL_ID;
-	bctx->nsei = NSEI;
-	bctx->ra_id.mnc = MNC;
-	bctx->ra_id.mcc = MCC;
-	bctx->ra_id.lac = PCU_LAC;
-	bctx->ra_id.rac = PCU_RAC;
-	bctx->bvci = BVCI;
-
 	llc_pdu = msgb_alloc_headroom(msg_len, msg_len,"llc_pdu");
 	msgb_tvlv_push(llc_pdu, BSSGP_IE_LLC_PDU, sizeof(uint8_t)*tbf->llc_index, tbf->llc_frame);
 	bssgp_tx_ul_ud(bctx, tbf->tlli, &qos_profile, llc_pdu);
+
+	return 0;
 }
 
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index 94d88d2..c47d6d4 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -235,7 +235,7 @@
 void write_packet_uplink_ack(bitvec * dest, struct gprs_rlcmac_tbf *tbf,
         uint8_t final);
 
-void gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
+int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
 
 void tbf_timer_cb(void *_tbf);
 
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index ee12636..21e454b 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -288,11 +288,6 @@
 
 #define BVCI 7
 
-#define MAX_LEN_PDU 60
-#define IE_LLC_PDU 14
-#define BLOCK_DATA_LEN 20
-#define BLOCK_LEN 23
-
 #define CELL_ID 0
 #define MNC 2
 #define MCC 262
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index 8ef5acc..2a5f2c7 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -27,13 +27,9 @@
 #include <getopt.h>
 
 struct gprs_rlcmac_bts *gprs_rlcmac_bts;
+extern struct gprs_nsvc *nsvc;
 uint16_t spoof_mcc = 0, spoof_mnc = 0;
 
-// TODO: We should move this parameters to config file.
-#define SGSN_IP "127.0.0.1"
-#define SGSN_PORT 23000
-#define NSVCI 4
-
 static void print_help()
 {
 	printf( "Some useful options:\n"
@@ -81,30 +77,10 @@
 	}
 }
 
-int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci)
-{
-	int rc = 0;
-	switch (event) {
-	case GPRS_NS_EVT_UNIT_DATA:
-		/* hand the message into the BSSGP implementation */
-		rc = gprs_bssgp_pcu_rcvmsg(msg);
-		break;
-	default:
-		LOGP(DPCU, LOGL_ERROR, "RLCMAC: Unknown event %u from NS\n", event);
-		if (msg)
-			talloc_free(msg);
-		rc = -EIO;
-		break;
-	}
-	return rc;
-}
-
 int main(int argc, char *argv[])
 {
-	uint16_t nsvci = NSVCI;
-	struct gprs_ns_inst *sgsn_nsi;
-	struct gprs_nsvc *nsvc;
 	struct gprs_rlcmac_bts *bts;
+	int rc;
 
 	bts = gprs_rlcmac_bts = talloc_zero(NULL, struct gprs_rlcmac_bts);
 	if (!gprs_rlcmac_bts)
@@ -130,34 +106,10 @@
 		exit(0);
 	}
 
-	pcu_l1if_open();
+	rc = pcu_l1if_open();
+	if (rc < 0)
+		return rc;
 
-	sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, NULL);
-	bssgp_nsi = sgsn_nsi;
-
-	if (!bssgp_nsi)
-	{
-		LOGP(DPCU, LOGL_ERROR, "Unable to instantiate NS\n");
-		exit(1);
-	}
-	bctx = btsctx_alloc(BVCI, NSEI);
-	bctx->cell_id = CELL_ID;
-	bctx->nsei = NSEI;
-	bctx->ra_id.mnc = spoof_mcc ? : MNC;
-	bctx->ra_id.mcc = spoof_mnc ? : MCC;
-	bctx->ra_id.lac = PCU_LAC;
-	bctx->ra_id.rac = PCU_RAC;
-	bctx->bvci = BVCI;
-	uint8_t cause = 39;
-	gprs_ns_nsip_listen(sgsn_nsi);
-
-	struct sockaddr_in dest;
-	dest.sin_family = AF_INET;
-	dest.sin_port = htons(SGSN_PORT);
-	inet_aton(SGSN_IP, &dest.sin_addr);
-
-	nsvc = gprs_ns_nsip_connect(sgsn_nsi, &dest, NSEI, nsvci);
-	unsigned i = 0;
 	while (1) 
 	{
 		osmo_gsm_timers_check();
@@ -165,13 +117,11 @@
 		osmo_gsm_timers_update();
 
 		osmo_select_main(0);
-		if (i == 7)
-		{
-			bssgp_tx_bvc_reset(bctx, BVCI, cause);
-		}
-		i++;
 	}
 
+	pcu_l1if_close();
 	talloc_free(gprs_rlcmac_bts);
+
+	return 0;
 }