<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/22210">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
pespin: Looks good to me, but someone else must approve
daniel: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gprs_ns2: implement BLOCK/UNBLOCK of a NSVC by vty<br><br>The vty should be able to block or unblock a specific NSVC.<br>Further more this case is special for the UNITDATA as those<br>can be still received until the other side response to the BLOCK PDU.<br><br>Related: OS#4939<br>Change-Id: Ic0ce3c5fabc8644cc1ee71a8f6dd783fadf7b84d<br>---<br>M src/gb/gprs_ns2_internal.h<br>M src/gb/gprs_ns2_vc_fsm.c<br>M src/gb/gprs_ns2_vty2.c<br>M tests/gb/gprs_ns2_test.c<br>M tests/gb/gprs_ns2_test.ok<br>5 files changed, 206 insertions(+), 8 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h</span><br><span>index 5404ed3..cb5c2bd 100644</span><br><span>--- a/src/gb/gprs_ns2_internal.h</span><br><span>+++ b/src/gb/gprs_ns2_internal.h</span><br><span>@@ -318,6 +318,8 @@</span><br><span> int gprs_ns2_vc_rx(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp);</span><br><span> int gprs_ns2_vc_is_alive(struct gprs_ns2_vc *nsvc);</span><br><span> int gprs_ns2_vc_is_unblocked(struct gprs_ns2_vc *nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+int ns2_vc_block(struct gprs_ns2_vc *nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+int ns2_vc_unblock(struct gprs_ns2_vc *nsvc);</span><br><span> </span><br><span> /* nse */</span><br><span> void ns2_nse_notify_unblocked(struct gprs_ns2_vc *nsvc, bool unblocked);</span><br><span>diff --git a/src/gb/gprs_ns2_vc_fsm.c b/src/gb/gprs_ns2_vc_fsm.c</span><br><span>index 641fcc3..8604bbe 100644</span><br><span>--- a/src/gb/gprs_ns2_vc_fsm.c</span><br><span>+++ b/src/gb/gprs_ns2_vc_fsm.c</span><br><span>@@ -59,6 +59,10 @@</span><br><span> * It can change during runtime. The side which blocks an unblocked side.*/</span><br><span> bool initiate_block;</span><br><span> bool initiate_reset;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* if blocked by O&M/vty */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool om_blocked;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* if unitdata is forwarded to the user */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool accept_unitdata;</span><br><span> </span><br><span> /* the alive counter is present in all states */</span><br><span> struct {</span><br><span>@@ -111,7 +115,9 @@</span><br><span> </span><br><span> GPRS_NS2_EV_UNITDATA,</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- GPRS_NS2_EV_FORCE_UNCONFIGURED, /* called via vty for tests */</span><br><span style="color: hsl(120, 100%, 40%);">+ GPRS_NS2_EV_FORCE_UNCONFIGURED, /* called via vty for tests */</span><br><span style="color: hsl(120, 100%, 40%);">+ GPRS_NS2_EV_REQ_OM_BLOCK, /* vty cmd: block */</span><br><span style="color: hsl(120, 100%, 40%);">+ GPRS_NS2_EV_REQ_OM_UNBLOCK, /* vty cmd: unblock*/</span><br><span> };</span><br><span> </span><br><span> static const struct value_string gprs_ns2_vc_event_names[] = {</span><br><span>@@ -127,6 +133,8 @@</span><br><span> { GPRS_NS2_EV_STATUS, "STATUS" },</span><br><span> { GPRS_NS2_EV_UNITDATA, "UNITDATA" },</span><br><span> { GPRS_NS2_EV_FORCE_UNCONFIGURED, "FORCE_UNCONFIGURED" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { GPRS_NS2_EV_REQ_OM_BLOCK, "REQ-O&M-BLOCK"},</span><br><span style="color: hsl(120, 100%, 40%);">+ { GPRS_NS2_EV_REQ_OM_UNBLOCK, "REQ-O&M-UNBLOCK"},</span><br><span> { 0, NULL }</span><br><span> };</span><br><span> </span><br><span>@@ -245,6 +253,7 @@</span><br><span> if (old_state != GPRS_NS2_ST_RESET)</span><br><span> priv->N = 0;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ priv->accept_unitdata = false;</span><br><span> if (priv->initiate_reset)</span><br><span> ns2_tx_reset(priv->nsvc, NS_CAUSE_OM_INTERVENTION);</span><br><span> </span><br><span>@@ -283,8 +292,16 @@</span><br><span> if (old_state != GPRS_NS2_ST_BLOCKED)</span><br><span> priv->N = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (priv->initiate_block)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (priv->om_blocked) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* we are already blocked after a RESET */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (old_state == GPRS_NS2_ST_RESET) {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_del(&fi->timer);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_tx_block(priv->nsvc, NS_CAUSE_OM_INTERVENTION);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (priv->initiate_block) {</span><br><span> ns2_tx_unblock(priv->nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span> start_test_procedure(priv);</span><br><span> }</span><br><span>@@ -293,7 +310,24 @@</span><br><span> {</span><br><span> struct gprs_ns2_vc_priv *priv = fi->priv;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (priv->initiate_block) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (priv->om_blocked) {</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GPRS_NS2_EV_BLOCK_ACK:</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->accept_unitdata = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_del(&fi->timer);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GPRS_NS2_EV_BLOCK:</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->accept_unitdata = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_tx_block_ack(priv->nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_del(&fi->timer);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GPRS_NS2_EV_UNBLOCK:</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->accept_unitdata = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_tx_block(priv->nsvc, NS_CAUSE_OM_INTERVENTION);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_add(&fi->timer);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (priv->initiate_block) {</span><br><span> switch (event) {</span><br><span> case GPRS_NS2_EV_BLOCK:</span><br><span> /* TODO: BLOCK is a UNBLOCK_NACK */</span><br><span>@@ -303,6 +337,7 @@</span><br><span> ns2_tx_unblock_ack(priv->nsvc);</span><br><span> /* fall through */</span><br><span> case GPRS_NS2_EV_UNBLOCK_ACK:</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->accept_unitdata = true;</span><br><span> osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_UNBLOCKED,</span><br><span> 0, NS_TOUT_TNS_TEST);</span><br><span> break;</span><br><span>@@ -325,6 +360,7 @@</span><br><span> struct gprs_ns2_vc *nsvc = priv->nsvc;</span><br><span> struct gprs_ns2_nse *nse = nsvc->nse;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ priv->accept_unitdata = true;</span><br><span> ns2_nse_notify_unblocked(nsvc, true);</span><br><span> ns2_prim_status_ind(nse, nsvc, 0, NS_AFF_CAUSE_VC_RECOVERY);</span><br><span> }</span><br><span>@@ -446,10 +482,19 @@</span><br><span> case GPRS_NS2_ST_BLOCKED:</span><br><span> if (priv->initiate_block) {</span><br><span> priv->N++;</span><br><span style="color: hsl(0, 100%, 40%);">- if (priv->N <= nsi->timeout[NS_TOUT_TNS_BLOCK_RETRIES]) {</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED, nsi->timeout[NS_TOUT_TNS_BLOCK], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (priv->om_blocked) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (priv->N <= nsi->timeout[NS_TOUT_TNS_BLOCK_RETRIES]) {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED, nsi->timeout[NS_TOUT_TNS_BLOCK], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 7.2 stop accepting data when BLOCK PDU not responded */</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->accept_unitdata = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> } else {</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_RESET, nsi->timeout[NS_TOUT_TNS_RESET], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (priv->N <= nsi->timeout[NS_TOUT_TNS_BLOCK_RETRIES]) {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED, nsi->timeout[NS_TOUT_TNS_BLOCK], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_RESET, nsi->timeout[NS_TOUT_TNS_RESET], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> }</span><br><span> break;</span><br><span>@@ -550,7 +595,7 @@</span><br><span> switch (fi->state) {</span><br><span> case GPRS_NS2_ST_BLOCKED:</span><br><span> /* 7.2.1: the BLOCKED_ACK might be lost */</span><br><span style="color: hsl(0, 100%, 40%);">- if (priv->initiate_block) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (priv->accept_unitdata) {</span><br><span> gprs_ns2_recv_unitdata(fi, msg);</span><br><span> return;</span><br><span> }</span><br><span>@@ -576,6 +621,20 @@</span><br><span> return;</span><br><span> }</span><br><span> break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GPRS_NS2_EV_REQ_OM_BLOCK:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* vty cmd: block */</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->initiate_block = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->om_blocked = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED, nsi->timeout[NS_TOUT_TNS_BLOCK], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GPRS_NS2_EV_REQ_OM_UNBLOCK:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* vty cmd: unblock*/</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!priv->om_blocked)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ priv->om_blocked = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fi->state == GPRS_NS2_ST_BLOCKED)</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED, nsi->timeout[NS_TOUT_TNS_BLOCK], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>@@ -595,7 +654,9 @@</span><br><span> S(GPRS_NS2_EV_RESET) |</span><br><span> S(GPRS_NS2_EV_ALIVE) |</span><br><span> S(GPRS_NS2_EV_ALIVE_ACK) |</span><br><span style="color: hsl(0, 100%, 40%);">- S(GPRS_NS2_EV_FORCE_UNCONFIGURED),</span><br><span style="color: hsl(120, 100%, 40%);">+ S(GPRS_NS2_EV_FORCE_UNCONFIGURED) |</span><br><span style="color: hsl(120, 100%, 40%);">+ S(GPRS_NS2_EV_REQ_OM_BLOCK) |</span><br><span style="color: hsl(120, 100%, 40%);">+ S(GPRS_NS2_EV_REQ_OM_UNBLOCK),</span><br><span> .allstate_action = gprs_ns2_vc_fsm_allstate_action,</span><br><span> .cleanup = gprs_ns2_vc_fsm_clean,</span><br><span> .timer_cb = gprs_ns2_vc_fsm_timer_cb,</span><br><span>@@ -653,6 +714,22 @@</span><br><span> return osmo_fsm_inst_dispatch(nsvc->fi, GPRS_NS2_EV_FORCE_UNCONFIGURED, NULL);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Block a NS-VC.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param nsvc the virtual circuit</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success; negative on error */</span><br><span style="color: hsl(120, 100%, 40%);">+int ns2_vc_block(struct gprs_ns2_vc *nsvc)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return osmo_fsm_inst_dispatch(nsvc->fi, GPRS_NS2_EV_REQ_OM_BLOCK, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Unblock a NS-VC.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param nsvc the virtual circuit</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success; negative on error */</span><br><span style="color: hsl(120, 100%, 40%);">+int ns2_vc_unblock(struct gprs_ns2_vc *nsvc)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return osmo_fsm_inst_dispatch(nsvc->fi, GPRS_NS2_EV_REQ_OM_UNBLOCK, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! entry point for messages from the driver/VL</span><br><span> * \param nsvc virtual circuit on which the message was received</span><br><span> * \param msg message that was received</span><br><span>diff --git a/src/gb/gprs_ns2_vty2.c b/src/gb/gprs_ns2_vty2.c</span><br><span>index 5af8fbc..94302ef 100644</span><br><span>--- a/src/gb/gprs_ns2_vty2.c</span><br><span>+++ b/src/gb/gprs_ns2_vty2.c</span><br><span>@@ -1503,6 +1503,33 @@</span><br><span> return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(nsvc_block, nsvc_block_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "nsvc <0-65535> (block|unblock)",</span><br><span style="color: hsl(120, 100%, 40%);">+ "NS Virtual Connection\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ NSVCI_STR</span><br><span style="color: hsl(120, 100%, 40%);">+ "Block a NSVC. As cause code O&M intervention will be used.\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Unblock a NSVC. As cause code O&M intervention will be used.\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_inst *nsi = vty_nsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_vc *nsvc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t id = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ nsvc = gprs_ns2_nsvc_by_nsvci(nsi, id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!nsvc) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Could not find NSVCI %05u%s", id, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(argv[1], "block")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_vc_block(nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_vc_unblock(nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void log_set_nse_filter(struct log_target *target,</span><br><span> struct gprs_ns2_nse *nse)</span><br><span> {</span><br><span>@@ -1608,6 +1635,7 @@</span><br><span> install_lib_element_ve(&logging_fltr_nsvc_cmd);</span><br><span> </span><br><span> install_lib_element(ENABLE_NODE, &nsvc_force_unconf_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_lib_element(ENABLE_NODE, &nsvc_block_cmd);</span><br><span> </span><br><span> install_lib_element(CFG_LOG_NODE, &logging_fltr_nse_cmd);</span><br><span> install_lib_element(CFG_LOG_NODE, &logging_fltr_nsvc_cmd);</span><br><span>diff --git a/tests/gb/gprs_ns2_test.c b/tests/gb/gprs_ns2_test.c</span><br><span>index bcfd460..315a4d0 100644</span><br><span>--- a/tests/gb/gprs_ns2_test.c</span><br><span>+++ b/tests/gb/gprs_ns2_test.c</span><br><span>@@ -20,6 +20,7 @@</span><br><span> </span><br><span> #include <osmocom/core/fsm.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span> #include <osmocom/core/application.h></span><br><span> #include <osmocom/core/utils.h></span><br><span> #include <osmocom/core/logging.h></span><br><span>@@ -44,6 +45,34 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *get_pdu(struct gprs_ns2_vc_bind *bind, enum ns_pdu_type pdu_type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns_hdr *nsh;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_wqueue *queue = bind->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (!llist_empty(&queue->msg_queue)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg = msgb_dequeue(&queue->msg_queue);</span><br><span style="color: hsl(120, 100%, 40%);">+ nsh = (struct gprs_ns_hdr *) msg->l2h;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (nsh->pdu_type == pdu_type)</span><br><span style="color: hsl(120, 100%, 40%);">+ return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static bool find_pdu(struct gprs_ns2_vc_bind *bind, enum ns_pdu_type pdu_type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = get_pdu(bind, pdu_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void clear_pdus(struct gprs_ns2_vc_bind *bind)</span><br><span> {</span><br><span> struct osmo_wqueue *queue = bind->priv;</span><br><span>@@ -147,6 +176,62 @@</span><br><span> </span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* setup NSE with 2x NSVCs.</span><br><span style="color: hsl(120, 100%, 40%);">+ * block 1x NSVC</span><br><span style="color: hsl(120, 100%, 40%);">+ * unblock 1x NSVC*/</span><br><span style="color: hsl(120, 100%, 40%);">+void test_block_unblock_nsvc(void *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_inst *nsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_vc_bind *bind[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_nse *nse;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_vc *nsvc[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns_hdr *nsh;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ char idbuf[32];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("--- Testing NSE block unblock nsvc\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("---- Create NSE + Binds\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ bind[0] = dummy_bind(nsi, "bblock1");</span><br><span style="color: hsl(120, 100%, 40%);">+ bind[1] = dummy_bind(nsi, "bblock2");</span><br><span style="color: hsl(120, 100%, 40%);">+ nse = gprs_ns2_create_nse(nsi, 1001, GPRS_NS2_LL_UDP, NS2_DIALECT_STATIC_RESETBLOCK);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(nse);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (int i=0; i<2; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("---- Create NSVC[i]\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i);</span><br><span style="color: hsl(120, 100%, 40%);">+ nsvc[i] = ns2_vc_alloc(bind[i], nse, false, NS2_VC_MODE_BLOCKRESET, idbuf);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(nsvc[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ nsvc[i]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* ensure the fi->state works correct */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(gprs_ns2_vc_is_unblocked(nsvc[i]));</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_nse_notify_unblocked(nsvc[i], true);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* both nsvcs are unblocked and alive. Let's block it. */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(!find_pdu(bind[0], NS_PDUT_BLOCK));</span><br><span style="color: hsl(120, 100%, 40%);">+ clear_pdus(bind[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_vc_block(nsvc[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(find_pdu(bind[0], NS_PDUT_BLOCK));</span><br><span style="color: hsl(120, 100%, 40%);">+ /* state == BLOCKED */</span><br><span style="color: hsl(120, 100%, 40%);">+ clear_pdus(bind[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* now unblocking it */</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_vc_unblock(nsvc[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(find_pdu(bind[0], NS_PDUT_UNBLOCK));</span><br><span style="color: hsl(120, 100%, 40%);">+ clear_pdus(bind[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "test_unblock");</span><br><span style="color: hsl(120, 100%, 40%);">+ msg->l2h = msgb_put(msg, sizeof(*nsh));</span><br><span style="color: hsl(120, 100%, 40%);">+ nsh = (struct gprs_ns_hdr *) msg->l2h;</span><br><span style="color: hsl(120, 100%, 40%);">+ nsh->pdu_type = NS_PDUT_UNBLOCK_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_recv_vc(nsvc[0], msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(gprs_ns2_vc_is_unblocked(nsvc[0]));</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_ns2_free(nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("--- Finish NSE block unblock nsvc\n");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span> void *ctx = talloc_named_const(NULL, 0, "gprs_ns2_test");</span><br><span>@@ -159,6 +244,7 @@</span><br><span> </span><br><span> printf("===== NS2 protocol test START\n");</span><br><span> test_nse_transfer_cap(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_block_unblock_nsvc(ctx);</span><br><span> printf("===== NS2 protocol test END\n\n");</span><br><span> </span><br><span> talloc_free(ctx);</span><br><span>diff --git a/tests/gb/gprs_ns2_test.ok b/tests/gb/gprs_ns2_test.ok</span><br><span>index 62bbbfe..27c72fa 100644</span><br><span>--- a/tests/gb/gprs_ns2_test.ok</span><br><span>+++ b/tests/gb/gprs_ns2_test.ok</span><br><span>@@ -6,5 +6,10 @@</span><br><span> ---- Test with NSVC[2]</span><br><span> ---- Test with NSVC[1] removed</span><br><span> --- Finish NSE transfer cap</span><br><span style="color: hsl(120, 100%, 40%);">+--- Testing NSE block unblock nsvc</span><br><span style="color: hsl(120, 100%, 40%);">+---- Create NSE + Binds</span><br><span style="color: hsl(120, 100%, 40%);">+---- Create NSVC[i]</span><br><span style="color: hsl(120, 100%, 40%);">+---- Create NSVC[i]</span><br><span style="color: hsl(120, 100%, 40%);">+--- Finish NSE block unblock nsvc</span><br><span> ===== NS2 protocol test END</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/22210">change 22210</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/22210"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ic0ce3c5fabc8644cc1ee71a8f6dd783fadf7b84d </div>
<div style="display:none"> Gerrit-Change-Number: 22210 </div>
<div style="display:none"> Gerrit-PatchSet: 17 </div>
<div style="display:none"> Gerrit-Owner: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-Assignee: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>