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); unsigned int num_ip6_elems);
/* transmit message over a VC */ /* transmit message over a VC */
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);
int ns2_tx_block_ack(struct gprs_ns2_vc *nsvc); 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(struct gprs_ns2_vc *nsvc, uint8_t cause);
int ns2_tx_reset_ack(struct gprs_ns2_vc *nsvc); 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. /*! 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] vc NS-VC on which the NS-BLOCK is to be transmitted
* \param[in] cause Numeric NS Cause value * \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 */ * \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 msgb *msg;
struct gprs_ns_hdr *nsh; 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_NSE, nsvc->nse);
log_set_context(LOG_CTX_GB_NSVC, nsvc); 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; nsh->pdu_type = NS_PDUT_BLOCK;
msgb_tvlv_put(msg, NS_IE_CAUSE, 1, &cause); 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)); LOG_NS_SIGNAL(nsvc, "Tx", nsh->pdu_type, LOGL_INFO, " cause=%s\n", gprs_ns2_cause_str(cause));
return ns_vc_tx(nsvc, msg); 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. /*! 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] 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 */ * \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 msgb *msg;
struct gprs_ns_hdr *nsh; 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_NSE, nsvc->nse);
log_set_context(LOG_CTX_GB_NSVC, nsvc); 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 = (struct gprs_ns_hdr *) msg->l2h;
nsh->pdu_type = NS_PDUT_BLOCK_ACK; 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); LOG_NS_TX_SIGNAL(nsvc, nsh->pdu_type);
return ns_vc_tx(nsvc, msg); 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) { if (old_state == GPRS_NS2_ST_RESET) {
osmo_timer_del(&fi->timer); osmo_timer_del(&fi->timer);
} else { } 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) { } else if (priv->initiate_block) {
ns2_tx_unblock(priv->nsvc); 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; break;
case GPRS_NS2_EV_RX_BLOCK: case GPRS_NS2_EV_RX_BLOCK:
priv->accept_unitdata = false; priv->accept_unitdata = false;
ns2_tx_block_ack(priv->nsvc); ns2_tx_block_ack(priv->nsvc, NULL);
osmo_timer_del(&fi->timer); osmo_timer_del(&fi->timer);
break; break;
case GPRS_NS2_EV_RX_UNBLOCK: case GPRS_NS2_EV_RX_UNBLOCK:
priv->accept_unitdata = false; 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); osmo_timer_add(&fi->timer);
break; break;
} }
@ -382,7 +382,7 @@ static void ns2_st_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data)
switch (event) { switch (event) {
case GPRS_NS2_EV_RX_BLOCK: case GPRS_NS2_EV_RX_BLOCK:
/* TODO: BLOCK is a UNBLOCK_NACK */ /* TODO: BLOCK is a UNBLOCK_NACK */
ns2_tx_block_ack(priv->nsvc); ns2_tx_block_ack(priv->nsvc, NULL);
break; break;
case GPRS_NS2_EV_RX_UNBLOCK: case GPRS_NS2_EV_RX_UNBLOCK:
ns2_tx_unblock_ack(priv->nsvc); 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! */ /* we are on the receiving end. The initiator who sent RESET is responsible to UNBLOCK! */
switch (event) { switch (event) {
case GPRS_NS2_EV_RX_BLOCK: case GPRS_NS2_EV_RX_BLOCK:
ns2_tx_block_ack(priv->nsvc); ns2_tx_block_ack(priv->nsvc, NULL);
break; break;
case GPRS_NS2_EV_RX_UNBLOCK: case GPRS_NS2_EV_RX_UNBLOCK:
ns2_tx_unblock_ack(priv->nsvc); 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: case GPRS_NS2_EV_RX_BLOCK:
priv->initiate_block = false; priv->initiate_block = false;
priv->accept_unitdata = 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, osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED,
0, 2); 0, 2);
break; break;

View File

@ -439,7 +439,7 @@ void test_unitdata(void *ctx)
printf("---- Send Block NSVC[0]\n"); printf("---- Send Block NSVC[0]\n");
ns2_vc_block(nsvc[0]); 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 */ /* try to receive a unitdata - this should be dropped & freed by NS */
printf("---- Try to receive over blocked NSVC[0]\n"); printf("---- Try to receive over blocked NSVC[0]\n");