[PATCH 3/3] gb: Fix NS RESET/RESET_ACK abnormal cases

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/OpenBSC@lists.osmocom.org/.

Jacob Erlbeck jerlbeck at sysmocom.de
Tue Oct 22 10:22:41 UTC 2013


This changes the implementations for the reception of RESET and
RESET_ACK to be compatible with 3GPP TS 08.16, 7.3.1:

- Just send a RESET_ACK with correct values back to the SGSN when a
  RESET with an invalid NSVCI or NSEI has been received.
- Check RESET_ACK for matching NSEI and NSVCI.
- Ignore unexpected RESET_ACKs.

In addition, use RESET_ACK from a BSS to update the BSS source
address based on the NSVCI to be tolerant with changing UDP source
addresses/ports.

Sponsored-by: On-Waves ehf
---
 include/osmocom/gprs/gprs_ns.h |    5 +
 src/gb/gprs_ns.c               |  259 +++++++++++++++++++++++++++++++++-------
 tests/gb/gprs_ns_test.c        |    6 +
 tests/gb/gprs_ns_test.ok       |  104 +++++++---------
 4 files changed, 269 insertions(+), 105 deletions(-)

diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h
index b28c58d..296800e 100644
--- a/include/osmocom/gprs/gprs_ns.h
+++ b/include/osmocom/gprs/gprs_ns.h
@@ -36,6 +36,7 @@ enum ns_timeout {
 
 #define NSE_S_BLOCKED	0x0001
 #define NSE_S_ALIVE	0x0002
+#define NSE_S_RESET	0x0004
 
 /*! \brief Osmocom NS link layer types */
 enum gprs_ns_ll {
@@ -199,12 +200,16 @@ enum signal_ns {
 	S_NS_UNBLOCK,
 	S_NS_ALIVE_EXP,	/* Tns-alive expired more than N times */
 	S_NS_REPLACED, /* nsvc object is replaced (sets old_nsvc) */
+	S_NS_MISMATCH, /* got an unexpected IE (sets msg, pdu_type, ie_type) */
 };
 
 struct ns_signal_data {
 	struct gprs_nsvc *nsvc;
 	struct gprs_nsvc *old_nsvc;
 	uint8_t cause;
+	uint8_t pdu_type;
+	uint8_t ie_type;
+	struct msgb *msg;
 };
 
 void gprs_ns_set_log_ss(int ss);
diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c
index 6a35ad3..b50a700 100644
--- a/src/gb/gprs_ns.c
+++ b/src/gb/gprs_ns.c
@@ -102,6 +102,8 @@ enum ns_ctr {
 	NS_CTR_DEAD,
 	NS_CTR_REPLACED,
 	NS_CTR_NSEI_CHG,
+	NS_CTR_INV_VCI,
+	NS_CTR_INV_NSEI,
 };
 
 static const struct rate_ctr_desc nsvc_ctr_description[] = {
@@ -113,6 +115,8 @@ static const struct rate_ctr_desc nsvc_ctr_description[] = {
 	{ "dead",	"NS-VC gone dead count     " },
 	{ "replaced",	"NS-VC replaced other count" },
 	{ "nsei-chg",	"NS-VC changed NSEI        " },
+	{ "inv-nsvci",	"NS-VCI was invalid count  " },
+	{ "inv-nsei",	"NSEI was invalid count    " },
 };
 
 static const struct rate_ctr_group_desc nsvc_ctrg_desc = {
@@ -190,6 +194,7 @@ struct gprs_nsvc *gprs_nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci)
 
 	nsvc = talloc_zero(nsi, struct gprs_nsvc);
 	nsvc->nsvci = nsvci;
+	nsvc->nsvci_is_valid = 1;
 	/* before RESET procedure: BLOCKED and DEAD */
 	nsvc->state = NSE_S_BLOCKED;
 	nsvc->nsi = nsi;
@@ -224,6 +229,20 @@ static void ns_osmo_signal_dispatch(struct gprs_nsvc *nsvc, unsigned int signal,
 	osmo_signal_dispatch(SS_L_NS, signal, &nssd);
 }
 
+static void ns_osmo_signal_dispatch_mismatch(struct gprs_nsvc *nsvc,
+					     struct msgb *msg,
+					     uint8_t pdu_type, uint8_t ie_type)
+{
+	struct ns_signal_data nssd = {0};
+
+	nssd.nsvc     = nsvc;
+	nssd.pdu_type = pdu_type;
+	nssd.ie_type  = ie_type;
+	nssd.msg      = msg;
+
+	osmo_signal_dispatch(SS_L_NS, S_NS_MISMATCH, &nssd);
+}
+
 static void ns_osmo_signal_dispatch_replaced(struct gprs_nsvc *nsvc, struct gprs_nsvc *old_nsvc)
 {
 	struct ns_signal_data nssd = {0};
@@ -322,6 +341,8 @@ int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause)
 	LOGP(DNS, LOGL_INFO, "NSEI=%u Tx NS RESET (NSVCI=%u, cause=%s)\n",
 		nsvc->nsei, nsvc->nsvci, gprs_ns_cause_str(cause));
 
+	nsvc->state |= NSE_S_RESET;
+
 	msg->l2h = msgb_put(msg, sizeof(*nsh));
 	nsh = (struct gprs_ns_hdr *) msg->l2h;
 	nsh->pdu_type = NS_PDUT_RESET;
@@ -671,6 +692,49 @@ static int gprs_ns_rx_status(struct gprs_nsvc *nsvc, struct msgb *msg)
 	return 0;
 }
 
+/* Replace a nsvc object with another based on NSVCI.
+ * This function replaces looks for a NSVC with the given NSVCI and replaces it
+ * if possible and necessary. If replaced, the former value of *nsvc is
+ * returned in *old_nsvc.
+ * \return != 0 if *nsvc points to a matching NSVC.
+ */
+static int gprs_nsvc_replace_if_found(uint16_t nsvci,
+				      struct gprs_nsvc **nsvc,
+				      struct gprs_nsvc **old_nsvc)
+{
+	struct gprs_nsvc *matching_nsvc;
+
+	if ((*nsvc)->nsvci == nsvci) {
+		*old_nsvc = NULL;
+		return 1;
+	}
+
+	matching_nsvc = gprs_nsvc_by_nsvci((*nsvc)->nsi, nsvci);
+
+	if (!matching_nsvc)
+		return 0;
+
+	/* The NS-VCI is already used by this NS-VC */
+
+	char *old_peer;
+
+	/* Exchange the NS-VC objects */
+	*old_nsvc = *nsvc;
+	*nsvc     = matching_nsvc;
+
+	/* Do logging */
+	old_peer = talloc_strdup(*old_nsvc, gprs_ns_ll_str(*old_nsvc));
+	LOGP(DNS, LOGL_INFO, "NS-VC changed link (NSVCI=%u) from %s to %s\n",
+	     nsvci, old_peer, gprs_ns_ll_str(*nsvc));
+
+	talloc_free(old_peer);
+
+	/* Do statistics */
+	rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_REPLACED]);
+
+	return 1;
+}
+
 /* Section 7.3 */
 static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
 {
@@ -678,7 +742,7 @@ static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
 	struct tlv_parsed tp;
 	uint8_t cause;
 	uint16_t nsvci, nsei;
-	struct gprs_nsvc *other_nsvc = NULL;
+	struct gprs_nsvc *orig_nsvc = NULL;
 	int rc;
 
 	rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
@@ -705,39 +769,42 @@ static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
 	     (*nsvc)->nsvci, (*nsvc)->nsvci_is_valid ? "" : "(invalid)",
 	     nsei, nsvci, gprs_ns_cause_str(cause));
 
-	if ((*nsvc)->nsvci_is_valid && (*nsvc)->nsvci != nsvci) {
-		/* NS-VCI has changed */
-		other_nsvc = gprs_nsvc_by_nsvci((*nsvc)->nsi, nsvci);
-
-		if (other_nsvc) {
-			/* The NS-VCI is already used by this NS-VC */
-
-			struct gprs_nsvc *tmp_nsvc;
-			char *old_peer;
-
-			/* Exchange the NS-VC objects */
-			tmp_nsvc = *nsvc;
-			*nsvc = other_nsvc;
-			other_nsvc = tmp_nsvc;
-
-			/* Do logging */
-			old_peer = talloc_strdup(other_nsvc,
-						 gprs_ns_ll_str(other_nsvc));
-			LOGP(DNS, LOGL_INFO,
-			     "NS-VC changed link (NSVCI=%u) from %s to %s\n",
-			     nsvci, old_peer, gprs_ns_ll_str(*nsvc));
-
-			talloc_free(old_peer);
-
-			/* Do statistics */
-			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_REPLACED]);
+	if (!(*nsvc)->nsvci_is_valid) {
+		/* It's a new uninitialised NS-VC, nothing to check here */
+	} else if ((*nsvc)->nsvci != nsvci) {
+		if ((*nsvc)->remote_end_is_sgsn) {
+			/* The incoming RESET doesn't match the NSVCI. Send an
+			 * appropriate RESET_ACK and ignore the RESET.
+			 * See 3GPP TS 08.16, 7.3.1, 2nd paragraph.
+			 */
+			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
+							 NS_PDUT_RESET,
+							 NS_IE_VCI);
+			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_VCI]);
+			gprs_ns_tx_reset_ack(*nsvc);
+			return 0;
 		}
+
+		/* NS-VCI has changed */
+		gprs_nsvc_replace_if_found(nsvci, nsvc, &orig_nsvc);
+
+	} else if ((*nsvc)->nsei != nsei) {
+		/* The incoming RESET doesn't match the NSEI. Send an
+		 * appropriate RESET_ACK and ignore the RESET.
+		 * See 3GPP TS 08.16, 7.3.1, 3rd paragraph.
+		 */
+		ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
+						 NS_PDUT_RESET,
+						 NS_IE_NSEI);
+		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
+		gprs_ns_tx_reset_ack(*nsvc);
+		return 0;
 	}
 
 	/* Mark NS-VC as blocked and alive */
 	(*nsvc)->state = NSE_S_BLOCKED | NSE_S_ALIVE;
 
-	if (other_nsvc) {
+	if (orig_nsvc) {
 		/* Check NSEI */
 		if ((*nsvc)->nsei != nsei) {
 			LOGP(DNS, LOGL_NOTICE,
@@ -751,11 +818,11 @@ static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
 			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_NSEI_CHG]);
 		}
 
-		ns_osmo_signal_dispatch_replaced(*nsvc, other_nsvc);
+		ns_osmo_signal_dispatch_replaced(*nsvc, orig_nsvc);
 
 		/* Update the ll info fields */
-		gprs_ns_ll_copy(*nsvc, other_nsvc);
-		gprs_ns_ll_clear(other_nsvc);
+		gprs_ns_ll_copy(*nsvc, orig_nsvc);
+		gprs_ns_ll_clear(orig_nsvc);
 	} else {
 		(*nsvc)->nsei  = nsei;
 		(*nsvc)->nsvci = nsvci;
@@ -775,6 +842,121 @@ static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
 	return rc;
 }
 
+static int gprs_ns_rx_reset_ack(struct gprs_nsvc **nsvc, struct msgb *msg)
+{
+	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
+	struct tlv_parsed tp;
+	uint16_t nsvci, nsei;
+	struct gprs_nsvc *orig_nsvc = NULL;
+	int rc;
+
+	rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
+			msgb_l2len(msg) - sizeof(*nsh), 0, 0);
+	if (rc < 0) {
+		LOGP(DNS, LOGL_ERROR, "NSEI=%u Rx NS RESET ACK "
+			"Error during TLV Parse\n", (*nsvc)->nsei);
+		return rc;
+	}
+
+	if (!TLVP_PRESENT(&tp, NS_IE_VCI) ||
+	    !TLVP_PRESENT(&tp, NS_IE_NSEI)) {
+		LOGP(DNS, LOGL_ERROR, "NS RESET ACK Missing mandatory IE\n");
+		gprs_ns_tx_status(*nsvc, NS_CAUSE_MISSING_ESSENT_IE, 0, msg);
+		return -EINVAL;
+	}
+
+	nsvci = ntohs(*(uint16_t *) TLVP_VAL(&tp, NS_IE_VCI));
+	nsei  = ntohs(*(uint16_t *) TLVP_VAL(&tp, NS_IE_NSEI));
+
+	LOGP(DNS, LOGL_INFO, "NSVCI=%u%s Rx NS RESET ACK (NSEI=%u, NSVCI=%u)\n",
+	     (*nsvc)->nsvci, (*nsvc)->nsvci_is_valid ? "" : "(invalid)",
+	     nsei, nsvci);
+
+	if (!((*nsvc)->state & NSE_S_RESET)) {
+		/* Not waiting for a RESET_ACK on this NS-VC, ignore it.
+		 * See 3GPP TS 08.16, 7.3.1, 5th paragraph.
+		 */
+		LOGP(DNS, LOGL_ERROR,
+		     "NS RESET ACK Discarding unexpected message for "
+		     "NS-VCI %d from SGSN NSEI=%d\n",
+		     nsvci, nsei);
+		return 0;
+	}
+
+	if (!(*nsvc)->nsvci_is_valid) {
+		LOGP(DNS, LOGL_NOTICE,
+		     "NS RESET ACK Uninitialised NS-VC (%u) for "
+		     "NS-VCI %d, NSEI=%d from %s\n",
+		     (*nsvc)->nsvci, nsvci, nsei, gprs_ns_ll_str(*nsvc));
+		return -EINVAL;
+	}
+
+	if ((*nsvc)->nsvci != nsvci) {
+		/* NS-VCI has changed */
+
+		/* if !0, use another NSVC object that matches the NSVCI */
+		int use_other_nsvc;
+
+		/* Only do this with BSS peers */
+		use_other_nsvc = !(*nsvc)->remote_end_is_sgsn;
+
+		if (use_other_nsvc)
+			/* Update *nsvc to point to the right NSVC object */
+			use_other_nsvc = gprs_nsvc_replace_if_found(nsvci, nsvc,
+								    &orig_nsvc);
+
+		if (!use_other_nsvc) {
+			/* The incoming RESET_ACK doesn't match the NSVCI.
+			 * See 3GPP TS 08.16, 7.3.1, 4th paragraph.
+			 */
+			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
+							 NS_PDUT_RESET_ACK,
+							 NS_IE_VCI);
+			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_VCI]);
+			LOGP(DNS, LOGL_ERROR,
+			     "NS RESET ACK Unknown NS-VCI %d (%s NSEI=%d) "
+			     "from %s\n",
+			     nsvci,
+			     (*nsvc)->remote_end_is_sgsn ? "SGSN" : "BSS",
+			     nsei, gprs_ns_ll_str(*nsvc));
+			return -EINVAL;
+		}
+
+		/* Notify others */
+		ns_osmo_signal_dispatch_replaced(*nsvc, orig_nsvc);
+
+		/* Update the ll info fields */
+		gprs_ns_ll_copy(*nsvc, orig_nsvc);
+		gprs_ns_ll_clear(orig_nsvc);
+	} else if ((*nsvc)->nsei != nsei) {
+		/* The incoming RESET_ACK doesn't match the NSEI.
+		 * See 3GPP TS 08.16, 7.3.1, 4th paragraph.
+		 */
+		ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
+						 NS_PDUT_RESET_ACK,
+						 NS_IE_NSEI);
+		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
+		LOGP(DNS, LOGL_ERROR,
+		     "NS RESET ACK Unknown NSEI %d (NS-VCI=%u) from %s\n",
+		     nsei, nsvci, gprs_ns_ll_str(*nsvc));
+		return -EINVAL;
+	}
+
+	/* Mark NS-VC as blocked and alive */
+	(*nsvc)->state = NSE_S_BLOCKED | NSE_S_ALIVE;
+	(*nsvc)->remote_state = NSE_S_BLOCKED | NSE_S_ALIVE;
+	rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_BLOCKED]);
+	if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
+		/* stop RESET timer */
+		osmo_timer_del(&(*nsvc)->timer);
+	}
+	/* Initiate TEST proc.: Send ALIVE and start timer */
+	rc = gprs_ns_tx_simple(*nsvc, NS_PDUT_ALIVE);
+	nsvc_start_timer(*nsvc, NSVC_TIMER_TNS_TEST);
+
+	return rc;
+}
+
 static int gprs_ns_rx_block(struct gprs_nsvc *nsvc, struct msgb *msg)
 {
 	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
@@ -943,6 +1125,7 @@ int gprs_ns_vc_create(struct gprs_ns_inst *nsi, struct msgb *msg,
 		     "from %s for non-existing NS-VC\n",
 		     nsh->pdu_type, gprs_ns_ll_str(fallback_nsvc));
 		fallback_nsvc->nsvci = fallback_nsvc->nsei = 0xfffe;
+		fallback_nsvc->nsvci_is_valid = 0;
 		fallback_nsvc->state = NSE_S_ALIVE;
 
 		rc = gprs_ns_tx_status(fallback_nsvc,
@@ -1056,18 +1239,7 @@ int gprs_ns_process_msg(struct gprs_ns_inst *nsi, struct msgb *msg,
 		rc = gprs_ns_rx_reset(nsvc, msg);
 		break;
 	case NS_PDUT_RESET_ACK:
-		LOGP(DNS, LOGL_INFO, "NSEI=%u Rx NS RESET ACK\n", (*nsvc)->nsei);
-		/* mark NS-VC as blocked + active */
-		(*nsvc)->state = NSE_S_BLOCKED | NSE_S_ALIVE;
-		(*nsvc)->remote_state = NSE_S_BLOCKED | NSE_S_ALIVE;
-		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_BLOCKED]);
-		if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
-			/* stop RESET timer */
-			osmo_timer_del(&(*nsvc)->timer);
-		}
-		/* Initiate TEST proc.: Send ALIVE and start timer */
-		rc = gprs_ns_tx_simple(*nsvc, NS_PDUT_ALIVE);
-		nsvc_start_timer(*nsvc, NSVC_TIMER_TNS_TEST);
+		rc = gprs_ns_rx_reset_ack(nsvc, msg);
 		break;
 	case NS_PDUT_UNBLOCK:
 		/* Section 7.2: unblocking procedure */
@@ -1322,6 +1494,7 @@ struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi,
 	nsvc->ip.bts_addr = *dest;
 	nsvc->nsei = nsei;
 	nsvc->nsvci = nsvci;
+	nsvc->nsvci_is_valid = 1;
 	nsvc->remote_end_is_sgsn = 1;
 
 	gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
diff --git a/tests/gb/gprs_ns_test.c b/tests/gb/gprs_ns_test.c
index df7f18b..d2d2825 100644
--- a/tests/gb/gprs_ns_test.c
+++ b/tests/gb/gprs_ns_test.c
@@ -356,6 +356,12 @@ static int test_signal(unsigned int subsys, unsigned int signal,
 		       gprs_ns_ll_str(nssd->old_nsvc));
 		break;
 
+	case S_NS_MISMATCH:
+		printf("==> got signal NS_MISMATCH: 0x%04x/%s pdu=%d, ie=%d\n",
+		       nssd->nsvc->nsvci, gprs_ns_ll_str(nssd->nsvc),
+		       nssd->pdu_type, nssd->ie_type);
+		break;
+
 	default:
 		printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
 		       nssd->nsvc->nsvci,
diff --git a/tests/gb/gprs_ns_test.ok b/tests/gb/gprs_ns_test.ok
index ddd0b00..b3c3236 100644
--- a/tests/gb/gprs_ns_test.ok
+++ b/tests/gb/gprs_ns_test.ok
@@ -254,35 +254,21 @@ MESSAGE to BSS, msg length 12
 PROCESSING RESET_ACK from 0x01020304:2222
 03 01 82 10 01 04 82 10 00 
 
+==> got signal NS_REPLACED: 0x1001/1.2.3.4:1111 -> 0x2001/1.2.3.4:2222
 MESSAGE to BSS, msg length 1
 0a 
 
 result (RESET_ACK) = 1
 
 Current NS-VCIs:
-    VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222, blocked
-         NS-VC Block count         : 1
-    VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111, blocked
-         NS-VC Block count         : 1
+    VCI 0x2001, NSEI 0x2000, peer 0x00000000:0
+    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 2
+         NS-VC replaced other count: 1
 
 --- Setup VC 2 SGSN -> BSS (hits NSEI 2) ---
 
-MESSAGE to BSS, msg length 12
-02 00 81 01 01 82 20 01 04 82 20 00 
-
-PROCESSING RESET_ACK from 0x01020304:1111
-03 01 82 20 01 04 82 20 00 
-
-MESSAGE to BSS, msg length 1
-0a 
-
-result (RESET_ACK) = 1
-
-Current NS-VCIs:
-    VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222, blocked
-         NS-VC Block count         : 1
-    VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111, blocked
-         NS-VC Block count         : 2
+Failed to send RESET to 0.0.0.0:0
 
 --- Setup VC 1 SGSN -> BSS (hits NSEI 1) ---
 
@@ -298,10 +284,10 @@ MESSAGE to BSS, msg length 1
 result (RESET_ACK) = 1
 
 Current NS-VCIs:
-    VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222, blocked
-         NS-VC Block count         : 2
-    VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111, blocked
-         NS-VC Block count         : 2
+    VCI 0x2001, NSEI 0x2000, peer 0x00000000:0
+    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 3
+         NS-VC replaced other count: 1
 
 --- Setup VC 2 BSS -> SGSN ---
 
@@ -310,7 +296,6 @@ Setup NS-VC: remote 0x01020304:1111, NSVCI 0x2001(8193), NSEI 0x2000(8192)
 PROCESSING RESET from 0x01020304:1111
 02 00 81 01 01 82 20 01 04 82 20 00 
 
-==> got signal NS_REPLACED: 0x2001/1.2.3.4:2222 -> 0x1001/1.2.3.4:1111
 ==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:1111
 MESSAGE to BSS, msg length 9
 03 01 82 20 01 04 82 20 00 
@@ -344,61 +329,59 @@ result (ALIVE_ACK) = 0
 
 Current NS-VCIs:
     VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
-         NS-VC Block count         : 2
+    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 3
          NS-VC replaced other count: 1
-    VCI 0x1001, NSEI 0x1000, peer 0x00000000:0, blocked
-         NS-VC Block count         : 2
 
 --- Unexpected RESET_ACK VC 1, BSS -> SGSN ---
 
 PROCESSING RESET_ACK from 0x01020304:2222
 03 01 82 10 01 04 82 10 00 
 
-MESSAGE to BSS, msg length 15
-08 00 81 0a 02 89 03 01 82 10 01 04 82 10 00 
-
 result (RESET_ACK) = 0
 
 Current NS-VCIs:
     VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
-         NS-VC Block count         : 2
+    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 3
          NS-VC replaced other count: 1
-    VCI 0x1001, NSEI 0x1000, peer 0x00000000:0, blocked
-         NS-VC Block count         : 2
 
 ---  RESET_ACK with invalid NSEI, BSS -> SGSN ---
 
+MESSAGE to BSS, msg length 12
+02 00 81 01 01 82 10 01 04 82 10 00 
+
 PROCESSING RESET_ACK from 0x01020304:2222
 03 01 82 10 01 04 82 f0 00 
 
-MESSAGE to BSS, msg length 15
-08 00 81 0a 02 89 03 01 82 10 01 04 82 f0 00 
-
-result (RESET_ACK) = 0
+==> got signal NS_MISMATCH: 0x1001/1.2.3.4:2222 pdu=3, ie=4
+result (RESET_ACK) = -22
 
 Current NS-VCIs:
     VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
-         NS-VC Block count         : 2
+    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 3
          NS-VC replaced other count: 1
-    VCI 0x1001, NSEI 0x1000, peer 0x00000000:0, blocked
-         NS-VC Block count         : 2
+         NSEI was invalid count    : 1
 
 ---  RESET_ACK with invalid NSVCI, BSS -> SGSN ---
 
+MESSAGE to BSS, msg length 12
+02 00 81 01 01 82 10 01 04 82 10 00 
+
 PROCESSING RESET_ACK from 0x01020304:2222
 03 01 82 f0 01 04 82 10 00 
 
-MESSAGE to BSS, msg length 15
-08 00 81 0a 02 89 03 01 82 f0 01 04 82 10 00 
-
-result (RESET_ACK) = 0
+==> got signal NS_MISMATCH: 0x1001/1.2.3.4:2222 pdu=3, ie=1
+result (RESET_ACK) = -22
 
 Current NS-VCIs:
     VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
-         NS-VC Block count         : 2
+    VCI 0x1001, NSEI 0x1000, peer 0x01020304:2222, blocked
+         NS-VC Block count         : 3
          NS-VC replaced other count: 1
-    VCI 0x1001, NSEI 0x1000, peer 0x00000000:0, blocked
-         NS-VC Block count         : 2
+         NS-VCI was invalid count  : 1
+         NSEI was invalid count    : 1
 
 Current NS-VCIs:
 
@@ -456,36 +439,33 @@ Current NS-VCIs:
 PROCESSING RESET from 0x05060708:32000
 02 00 81 01 01 82 01 01 04 82 f0 00 
 
-==> got signal NS_RESET, NS-VC 0x0101/5.6.7.8:32000
+==> got signal NS_MISMATCH: 0x0101/5.6.7.8:32000 pdu=2, ie=4
 MESSAGE to SGSN, msg length 9
-03 01 82 01 01 04 82 f0 00 
-
-MESSAGE to SGSN, msg length 1
-0a 
+03 01 82 01 01 04 82 01 00 
 
-result (RESET) = 9
+result (RESET) = 0
 
 Current NS-VCIs:
-    VCI 0x0101, NSEI 0xf000, peer 0x05060708:32000, blocked
+    VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000, blocked
          NS-VC Block count         : 1
+         NSEI was invalid count    : 1
 
 --- RESET with invalid NSVCI, SGSN -> BSS ---
 
 PROCESSING RESET from 0x05060708:32000
 02 00 81 01 01 82 f0 01 04 82 01 00 
 
-==> got signal NS_RESET, NS-VC 0xf001/5.6.7.8:32000
+==> got signal NS_MISMATCH: 0x0101/5.6.7.8:32000 pdu=2, ie=1
 MESSAGE to SGSN, msg length 9
-03 01 82 f0 01 04 82 01 00 
-
-MESSAGE to SGSN, msg length 1
-0a 
+03 01 82 01 01 04 82 01 00 
 
-result (RESET) = 9
+result (RESET) = 0
 
 Current NS-VCIs:
-    VCI 0xf001, NSEI 0x0100, peer 0x05060708:32000, blocked
+    VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000, blocked
          NS-VC Block count         : 1
+         NS-VCI was invalid count  : 1
+         NSEI was invalid count    : 1
 
 Current NS-VCIs:
 
-- 
1.7.9.5





More information about the OpenBSC mailing list