<p>lynxis lazus has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/24923">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">WIP: gprs_ns2: start use (ref) counting<br><br>Also avoid recursive free() rounds within the ns2 code<br><br>Change-Id: I03cb2419926c639d4bd357a33ce8008c50cd3bee<br>---<br>M src/gb/gprs_ns2.c<br>M src/gb/gprs_ns2_internal.h<br>M src/gb/gprs_ns2_sns.c<br>M tests/gb/gprs_ns2_test.c<br>M tests/gb/gprs_ns2_test.ok<br>5 files changed, 137 insertions(+), 17 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/23/24923/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c</span><br><span>index 3eb59e5..09286ec 100644</span><br><span>--- a/src/gb/gprs_ns2.c</span><br><span>+++ b/src/gb/gprs_ns2.c</span><br><span>@@ -236,6 +236,8 @@</span><br><span> { 0, NULL }</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void ns2_free_nse(struct gprs_ns2_nse *nse);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! string-format a given NS-VC into a user-supplied buffer.</span><br><span> * \param[in] buf user-allocated output buffer</span><br><span> * \param[in] buf_len size of user-allocated output buffer in bytes</span><br><span>@@ -631,9 +633,9 @@</span><br><span> * \param[in] nsvc NS-VC to destroy */</span><br><span> void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!nsvc)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!nsvc || nsvc->freed)</span><br><span> return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ nsvc->freed = true;</span><br><span> ns2_prim_status_ind(nsvc->nse, nsvc, 0, GPRS_NS2_AFF_CAUSE_VC_FAILURE);</span><br><span> </span><br><span> llist_del(&nsvc->list);</span><br><span>@@ -661,14 +663,18 @@</span><br><span> */</span><br><span> void gprs_ns2_free_nsvcs(struct gprs_ns2_nse *nse)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct gprs_ns2_vc *nsvc, *tmp;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_vc *nsvc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!nse)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!nse || nse->freed)</span><br><span> return;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each_entry_safe(nsvc, tmp, &nse->nsvc, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_get(nse, NSE_USE_LIST);</span><br><span style="color: hsl(120, 100%, 40%);">+loop:</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(nsvc, &nse->nsvc, list) {</span><br><span> gprs_ns2_free_nsvc(nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto loop;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_put(nse, NSE_USE_LIST);</span><br><span> }</span><br><span> </span><br><span> /*! Allocate a message buffer for use with the NS2 stack. */</span><br><span>@@ -778,6 +784,30 @@</span><br><span> return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int nse_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_nse *nse = e->use_count->talloc_object;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_use_count_entry *e2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int32_t other_count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int32_t core_count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!e->use)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (e->count < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -ERANGE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(e2, &nse->use_count.use_counts, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcmp(e2->use, NSE_USE_CORE) == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ core_count += e2->count;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ other_count += e2->count;</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 (other_count <= 0 && core_count <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_free_nse(nse);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Create a NS Entity within given NS instance.</span><br><span> * \param[in] nsi NS instance in which to create NS Entity</span><br><span> * \param[in] nsei NS Entity Identifier of to-be-created NSE</span><br><span>@@ -813,6 +843,11 @@</span><br><span> nse->mtu = 0;</span><br><span> llist_add_tail(&nse->list, &nsi->nse);</span><br><span> INIT_LLIST_HEAD(&nse->nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ nse->use_count = (struct osmo_use_count){</span><br><span style="color: hsl(120, 100%, 40%);">+ .talloc_object = nse,</span><br><span style="color: hsl(120, 100%, 40%);">+ .use_cb = nse_use_cb,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_get(nse, NSE_USE_CORE);</span><br><span> </span><br><span> return nse;</span><br><span> }</span><br><span>@@ -871,26 +906,35 @@</span><br><span> return nse->nsei;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! Destroy given NS Entity.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] nse NS Entity to destroy */</span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_ns2_free_nse(struct gprs_ns2_nse *nse)</span><br><span style="color: hsl(120, 100%, 40%);">+static void ns2_free_nse(struct gprs_ns2_nse *nse)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!nse)</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_vc *nsvc, *nsvc2;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!nse || nse->freed)</span><br><span> return;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ nse->freed = true;</span><br><span> nse->alive = false;</span><br><span> if (nse->bss_sns_fi) {</span><br><span> osmo_fsm_inst_term(nse->bss_sns_fi, OSMO_FSM_TERM_REQUEST, NULL);</span><br><span> nse->bss_sns_fi = NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- gprs_ns2_free_nsvcs(nse);</span><br><span style="color: hsl(0, 100%, 40%);">- ns2_prim_status_ind(nse, NULL, 0, GPRS_NS2_AFF_CAUSE_FAILURE);</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry_safe(nsvc, nsvc2, &nse->nsvc, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_ns2_free_nsvc(nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_prim_status_ind(nse, NULL, 0, GPRS_NS2_AFF_CAUSE_FAILURE);</span><br><span> llist_del(&nse->list);</span><br><span> talloc_free(nse);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Destroy given NS Entity.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] nse NS Entity to destroy */</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_ns2_free_nse(struct gprs_ns2_nse *nse)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_put(nse, NSE_USE_CORE);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi)</span><br><span> {</span><br><span> struct gprs_ns2_nse *nse, *ntmp;</span><br><span>@@ -1240,11 +1284,14 @@</span><br><span> {</span><br><span> struct gprs_ns2_vc *nsvc, *tmp;</span><br><span> int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_get(nse, NSE_USE_LIST);</span><br><span> llist_for_each_entry_safe(nsvc, tmp, &nse->nsvc, list) {</span><br><span> rc = cb(nsvc, cb_data);</span><br><span> if (rc < 0)</span><br><span> return rc;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_put(nse, NSE_USE_LIST);</span><br><span> </span><br><span> return 0;</span><br><span> }</span><br><span>@@ -1450,20 +1497,26 @@</span><br><span> void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind)</span><br><span> {</span><br><span> struct gprs_ns2_vc *nsvc, *tmp;</span><br><span style="color: hsl(0, 100%, 40%);">- struct gprs_ns2_nse *nse;</span><br><span style="color: hsl(0, 100%, 40%);">- if (!bind)</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_ns2_nse *nse, *nse2;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!bind || bind->freed)</span><br><span> return;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each_entry_safe(nsvc, tmp, &bind->nsvc, blist) {</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_ns2_free_nsvc(nsvc);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ bind->freed = true;</span><br><span> </span><br><span> if (gprs_ns2_is_ip_bind(bind)) {</span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each_entry(nse, &bind->nsi->nse, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry_safe(nse, nse2, &bind->nsi->nse, list) {</span><br><span> gprs_ns2_sns_del_bind(nse, bind);</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* because freeing a single nsvc might free all other nsvcs */</span><br><span style="color: hsl(120, 100%, 40%);">+loop:</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(nsvc, &bind->nsvc, blist) {</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_ns2_free_nsvc(nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto loop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (bind->driver->free_bind)</span><br><span> bind->driver->free_bind(bind);</span><br><span> </span><br><span>diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h</span><br><span>index 70e212a..65cfda6 100644</span><br><span>--- a/src/gb/gprs_ns2_internal.h</span><br><span>+++ b/src/gb/gprs_ns2_internal.h</span><br><span>@@ -6,6 +6,7 @@</span><br><span> #include <stdint.h></span><br><span> </span><br><span> #include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/use_count.h></span><br><span> #include <osmocom/gprs/protocol/gsm_08_16.h></span><br><span> #include <osmocom/gprs/gprs_ns2.h></span><br><span> </span><br><span>@@ -198,6 +199,11 @@</span><br><span> </span><br><span> /*! are we implementing the SGSN role? */</span><br><span> bool ip_sns_role_sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! recursive anchor */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool freed;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_use_count use_count;</span><br><span> };</span><br><span> </span><br><span> /*! Structure representing a single NS-VC */</span><br><span>@@ -242,6 +248,9 @@</span><br><span> enum gprs_ns2_vc_mode mode;</span><br><span> </span><br><span> struct osmo_fsm_inst *fi;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! recursive anchor */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool freed;</span><br><span> };</span><br><span> </span><br><span> /*! Structure repesenting a bind instance. E.g. IPv4 listen port. */</span><br><span>@@ -286,6 +295,9 @@</span><br><span> uint8_t sns_data_weight;</span><br><span> </span><br><span> struct osmo_stat_item_group *statg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! recursive anchor */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool freed;</span><br><span> };</span><br><span> </span><br><span> struct gprs_ns2_vc_driver {</span><br><span>@@ -294,6 +306,15 @@</span><br><span> void (*free_bind)(struct gprs_ns2_vc_bind *driver);</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define ns2_get(ns2_obj, use) \</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(osmo_use_count_get_put(&(ns2_obj)->use_count, use, 1) == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define ns2_put(ns2_obj, use) \</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(osmo_use_count_get_put(&(ns2_obj)->use_count, use, -1) == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define NSE_USE_CORE "ns2core"</span><br><span style="color: hsl(120, 100%, 40%);">+#define NSE_USE_LIST "ns2list"</span><br><span style="color: hsl(120, 100%, 40%);">+#define NSE_USE_SNS "ns2sns"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum ns2_cs ns2_create_vc(struct gprs_ns2_vc_bind *bind,</span><br><span> struct msgb *msg,</span><br><span> const struct osmo_sockaddr *remote,</span><br><span>diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c</span><br><span>index 642b47c..b4a8d7f 100644</span><br><span>--- a/src/gb/gprs_ns2_sns.c</span><br><span>+++ b/src/gb/gprs_ns2_sns.c</span><br><span>@@ -658,6 +658,7 @@</span><br><span> OSMO_ASSERT(false);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_get(nse, NSE_USE_LIST);</span><br><span> llist_for_each_entry_safe(nsvc, tmp, &nse->nsvc, list) {</span><br><span> remote = gprs_ns2_ip_vc_remote(nsvc);</span><br><span> /* all nsvc in NSE should be IP/UDP nsvc */</span><br><span>@@ -668,6 +669,7 @@</span><br><span> LOGPFSML(fi, LOGL_INFO, "DELETE NS-VC %s\n", gprs_ns2_ll_str(nsvc));</span><br><span> gprs_ns2_free_nsvc(nsvc);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_put(nse, NSE_USE_LIST);</span><br><span> </span><br><span> return 0;</span><br><span> }</span><br><span>@@ -1482,6 +1484,7 @@</span><br><span> struct ns2_sns_bind *sbind;</span><br><span> struct gprs_ns2_vc *nsvc, *nsvc2;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_get(nse, NSE_USE_SNS);</span><br><span> switch (event) {</span><br><span> case GPRS_SNS_EV_REQ_ADD_BIND:</span><br><span> sbind = data;</span><br><span>@@ -1528,6 +1531,7 @@</span><br><span> talloc_free(sbind);</span><br><span> break;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ ns2_put(nse, NSE_USE_SNS);</span><br><span> }</span><br><span> </span><br><span> /* validate the bss configuration (sns endpoint and binds)</span><br><span>diff --git a/tests/gb/gprs_ns2_test.c b/tests/gb/gprs_ns2_test.c</span><br><span>index 515d908..2322735 100644</span><br><span>--- a/tests/gb/gprs_ns2_test.c</span><br><span>+++ b/tests/gb/gprs_ns2_test.c</span><br><span>@@ -642,6 +642,43 @@</span><br><span> printf("--- Finish force unconfigured test\n");</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void test_use_count(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_vc_bind *loopbind;</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_ns2_vc *loop[2];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg, *other;</span><br><span style="color: hsl(120, 100%, 40%);">+ char idbuf[32];</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("--- Testing nse use count\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_clear(unitdata);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("---- Create 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%);">+ loopbind = loopback_bind(nsi, "loopback");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ // free SNS NSE with active NSVCs</span><br><span style="color: hsl(120, 100%, 40%);">+ // free SNS NSE with active NSVCs on a SNS/NSE event</span><br><span style="color: hsl(120, 100%, 40%);">+ // free a dynamic SNS NSE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ nse = gprs_ns2_create_nse(nsi, 1004, GPRS_NS2_LL_UDP, GPRS_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%);">+ for (i=0; i<2; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("---- Create NSVC[%d]\n", i);</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, GPRS_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%);">+ ns2_vc_fsm_start(nsvc[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_ns2_free_nse(nse);</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>@@ -663,6 +700,7 @@</span><br><span> test_unitdata_weights(ctx);</span><br><span> test_unconfigured(ctx);</span><br><span> test_mtu(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_use_count(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 8bae5b9..f4af60c 100644</span><br><span>--- a/tests/gb/gprs_ns2_test.ok</span><br><span>+++ b/tests/gb/gprs_ns2_test.ok</span><br><span>@@ -47,5 +47,9 @@</span><br><span> ---- Send a small UNITDATA to NSVC[0]</span><br><span> ---- Check if got mtu reported</span><br><span> --- Finish unitdata test</span><br><span style="color: hsl(120, 100%, 40%);">+--- Testing nse use count</span><br><span style="color: hsl(120, 100%, 40%);">+---- Create Binds</span><br><span style="color: hsl(120, 100%, 40%);">+---- Create NSVC[0]</span><br><span style="color: hsl(120, 100%, 40%);">+---- Create NSVC[1]</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/+/24923">change 24923</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/+/24923"/><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: I03cb2419926c639d4bd357a33ce8008c50cd3bee </div>
<div style="display:none"> Gerrit-Change-Number: 24923 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>