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
This commit is contained in:
Alexander Couzens 2021-09-07 01:10:38 +02:00 committed by laforge
parent 8ae40cbb91
commit 67cfc5dc9a
4 changed files with 27 additions and 15 deletions

View File

@ -422,8 +422,8 @@ int ns2_tx_sns_del(struct gprs_ns2_vc *nsvc,
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);

View File

@ -206,12 +206,18 @@ static int ns2_tx_simple(struct gprs_ns2_vc *nsvc, uint8_t pdu_type)
/*! 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 @@ int ns2_tx_block(struct gprs_ns2_vc *nsvc, uint8_t cause)
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 @@ int ns2_tx_block(struct gprs_ns2_vc *nsvc, uint8_t cause)
/*! 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 @@ int ns2_tx_block_ack(struct gprs_ns2_vc *nsvc)
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);

View File

@ -348,7 +348,7 @@ static void ns2_st_blocked_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
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 @@ static void ns2_st_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data)
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 @@ static void ns2_st_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data)
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 @@ static void ns2_st_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data)
/* 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 @@ static void ns2_st_unblocked(struct osmo_fsm_inst *fi, uint32_t event, void *dat
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;

View File

@ -439,7 +439,7 @@ void test_unitdata(void *ctx)
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");