ns2: message: BLOCK/BLOCK ACK allow to use a given NSVCI instead of using the nsvc nsvci
The BLOCK and BLOCK ACK PDUs can be send over a working NSVC to inform
the NSE that a NSVC is blocked.
Change-Id: I6189229fdc1f054e86811bc60cb7646e1f758a78
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index bfb12d9..a5d78d4 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -422,8 +422,8 @@
unsigned int num_ip6_elems);
/* transmit message over a VC */
-int ns2_tx_block(struct gprs_ns2_vc *nsvc, uint8_t cause);
-int ns2_tx_block_ack(struct gprs_ns2_vc *nsvc);
+int ns2_tx_block(struct gprs_ns2_vc *nsvc, uint8_t cause, uint16_t *nsvci);
+int ns2_tx_block_ack(struct gprs_ns2_vc *nsvc, uint16_t *nsvci);
int ns2_tx_reset(struct gprs_ns2_vc *nsvc, uint8_t cause);
int ns2_tx_reset_ack(struct gprs_ns2_vc *nsvc);
diff --git a/src/gb/gprs_ns2_message.c b/src/gb/gprs_ns2_message.c
index 5e3e025..90873ed 100644
--- a/src/gb/gprs_ns2_message.c
+++ b/src/gb/gprs_ns2_message.c
@@ -206,12 +206,18 @@
/*! Transmit a NS-BLOCK on a given NS-VC.
* \param[in] vc NS-VC on which the NS-BLOCK is to be transmitted
* \param[in] cause Numeric NS Cause value
+ * \param[in] nsvci if given this NSVCI will be encoded. If NULL the nsvc->nsvci will be used.
* \returns 0 in case of success */
-int ns2_tx_block(struct gprs_ns2_vc *nsvc, uint8_t cause)
+int ns2_tx_block(struct gprs_ns2_vc *nsvc, uint8_t cause, uint16_t *nsvci)
{
struct msgb *msg;
struct gprs_ns_hdr *nsh;
- uint16_t nsvci = osmo_htons(nsvc->nsvci);
+ uint16_t encoded_nsvci;
+
+ if (nsvci)
+ encoded_nsvci = osmo_htons(*nsvci);
+ else
+ encoded_nsvci = osmo_htons(nsvc->nsvci);
log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
log_set_context(LOG_CTX_GB_NSVC, nsvc);
@@ -229,7 +235,7 @@
nsh->pdu_type = NS_PDUT_BLOCK;
msgb_tvlv_put(msg, NS_IE_CAUSE, 1, &cause);
- msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *) &nsvci);
+ msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *) &encoded_nsvci);
LOG_NS_SIGNAL(nsvc, "Tx", nsh->pdu_type, LOGL_INFO, " cause=%s\n", gprs_ns2_cause_str(cause));
return ns_vc_tx(nsvc, msg);
@@ -237,12 +243,18 @@
/*! Transmit a NS-BLOCK-ACK on a given NS-VC.
* \param[in] nsvc NS-VC on which the NS-BLOCK is to be transmitted
+ * \param[in] nsvci if given this NSVCI will be encoded. If NULL the nsvc->nsvci will be used.
* \returns 0 in case of success */
-int ns2_tx_block_ack(struct gprs_ns2_vc *nsvc)
+int ns2_tx_block_ack(struct gprs_ns2_vc *nsvc, uint16_t *nsvci)
{
struct msgb *msg;
struct gprs_ns_hdr *nsh;
- uint16_t nsvci = osmo_htons(nsvc->nsvci);
+ uint16_t encoded_nsvci;
+
+ if (nsvci)
+ encoded_nsvci = osmo_htons(*nsvci);
+ else
+ encoded_nsvci = osmo_htons(nsvc->nsvci);
log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
log_set_context(LOG_CTX_GB_NSVC, nsvc);
@@ -257,7 +269,7 @@
nsh = (struct gprs_ns_hdr *) msg->l2h;
nsh->pdu_type = NS_PDUT_BLOCK_ACK;
- msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *) &nsvci);
+ msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *) &encoded_nsvci);
LOG_NS_TX_SIGNAL(nsvc, nsh->pdu_type);
return ns_vc_tx(nsvc, msg);
diff --git a/src/gb/gprs_ns2_vc_fsm.c b/src/gb/gprs_ns2_vc_fsm.c
index fa8cec2..a366c93 100644
--- a/src/gb/gprs_ns2_vc_fsm.c
+++ b/src/gb/gprs_ns2_vc_fsm.c
@@ -348,7 +348,7 @@
if (old_state == GPRS_NS2_ST_RESET) {
osmo_timer_del(&fi->timer);
} else {
- ns2_tx_block(priv->nsvc, NS_CAUSE_OM_INTERVENTION);
+ ns2_tx_block(priv->nsvc, NS_CAUSE_OM_INTERVENTION, NULL);
}
} else if (priv->initiate_block) {
ns2_tx_unblock(priv->nsvc);
@@ -369,12 +369,12 @@
break;
case GPRS_NS2_EV_RX_BLOCK:
priv->accept_unitdata = false;
- ns2_tx_block_ack(priv->nsvc);
+ ns2_tx_block_ack(priv->nsvc, NULL);
osmo_timer_del(&fi->timer);
break;
case GPRS_NS2_EV_RX_UNBLOCK:
priv->accept_unitdata = false;
- ns2_tx_block(priv->nsvc, NS_CAUSE_OM_INTERVENTION);
+ ns2_tx_block(priv->nsvc, NS_CAUSE_OM_INTERVENTION, NULL);
osmo_timer_add(&fi->timer);
break;
}
@@ -382,7 +382,7 @@
switch (event) {
case GPRS_NS2_EV_RX_BLOCK:
/* TODO: BLOCK is a UNBLOCK_NACK */
- ns2_tx_block_ack(priv->nsvc);
+ ns2_tx_block_ack(priv->nsvc, NULL);
break;
case GPRS_NS2_EV_RX_UNBLOCK:
ns2_tx_unblock_ack(priv->nsvc);
@@ -397,7 +397,7 @@
/* we are on the receiving end. The initiator who sent RESET is responsible to UNBLOCK! */
switch (event) {
case GPRS_NS2_EV_RX_BLOCK:
- ns2_tx_block_ack(priv->nsvc);
+ ns2_tx_block_ack(priv->nsvc, NULL);
break;
case GPRS_NS2_EV_RX_UNBLOCK:
ns2_tx_unblock_ack(priv->nsvc);
@@ -441,7 +441,7 @@
case GPRS_NS2_EV_RX_BLOCK:
priv->initiate_block = false;
priv->accept_unitdata = false;
- ns2_tx_block_ack(priv->nsvc);
+ ns2_tx_block_ack(priv->nsvc, NULL);
osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED,
0, 2);
break;
diff --git a/tests/gb/gprs_ns2_test.c b/tests/gb/gprs_ns2_test.c
index ad78a62..0221a8d 100644
--- a/tests/gb/gprs_ns2_test.c
+++ b/tests/gb/gprs_ns2_test.c
@@ -439,7 +439,7 @@
printf("---- Send Block NSVC[0]\n");
ns2_vc_block(nsvc[0]);
- ns2_tx_block_ack(loop[0]);
+ ns2_tx_block_ack(loop[0], NULL);
/* try to receive a unitdata - this should be dropped & freed by NS */
printf("---- Try to receive over blocked NSVC[0]\n");