<p>lynxis lazus has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/20271">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Use the new NS2 lib<br><br>Depends: Id7edb8feb96436ba170383fc62d43ceb16955d53 (libosmocore)<br>Change-Id: Ib389925cf5c9f18951af6242c31ea70476218e9a<br>---<br>M src/bts.h<br>M src/gprs_bssgp_pcu.cpp<br>M src/gprs_bssgp_pcu.h<br>M src/osmobts_sock.cpp<br>M src/pcu_l1_if.cpp<br>M src/pcu_main.cpp<br>M src/pcu_vty.c<br>M tests/emu/pcu_emu.cpp<br>M tests/tbf/TbfTest.cpp<br>9 files changed, 249 insertions(+), 188 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/71/20271/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/bts.h b/src/bts.h</span><br><span>index 5a1b162..e930463 100644</span><br><span>--- a/src/bts.h</span><br><span>+++ b/src/bts.h</span><br><span>@@ -174,6 +174,11 @@</span><br><span>   * more than one message, because they get sent so rarely. */</span><br><span>        struct msgb *app_info;</span><br><span>       uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */</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%);">+    /* main nsei */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_ns2_nse *nse;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint16_t nsei;</span><br><span> };</span><br><span> </span><br><span> enum {</span><br><span>diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp</span><br><span>index d008d02..8383afd 100644</span><br><span>--- a/src/gprs_bssgp_pcu.cpp</span><br><span>+++ b/src/gprs_bssgp_pcu.cpp</span><br><span>@@ -30,6 +30,7 @@</span><br><span> </span><br><span> extern "C" {</span><br><span>    #include <osmocom/gsm/protocol/gsm_23_003.h></span><br><span style="color: hsl(120, 100%, 40%);">+    #include <osmocom/gprs/protocol/gsm_08_16.h></span><br><span>   #include <osmocom/core/utils.h></span><br><span>        #include "coding_scheme.h"</span><br><span> }</span><br><span>@@ -51,7 +52,6 @@</span><br><span> extern bool spoof_mnc_3_digits;</span><br><span> </span><br><span> static void bvc_timeout(void *_priv);</span><br><span style="color: hsl(0, 100%, 40%);">-static int gprs_ns_reconnect(struct gprs_nsvc *nsvc);</span><br><span> </span><br><span> static int parse_ra_cap(struct tlv_parsed *tp, MS_Radio_Access_capability_t *rac)</span><br><span> {</span><br><span>@@ -549,75 +549,91 @@</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci)</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_ns_prim_status_cb(struct osmo_gprs_ns2_prim *nsp)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       int rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     switch (event) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case GPRS_NS_EVT_UNIT_DATA:</span><br><span style="color: hsl(0, 100%, 40%);">-             /* hand the message into the BSSGP implementation */</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = gprs_bssgp_pcu_rcvmsg(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+      switch (nsp->u.status.cause) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case NS_AFF_CAUSE_SNS_CONFIGURED:</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d SNS configured.\n", nsp->nsei);</span><br><span>              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DPCU, LOGL_NOTICE, "RLCMAC: Unknown event %u from NS\n", event);</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,</span><br><span style="color: hsl(0, 100%, 40%);">-  void *handler_data, void *signal_data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct ns_signal_data *nssd;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (subsys != SS_L_NS)</span><br><span style="color: hsl(0, 100%, 40%);">-          return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- nssd = (struct ns_signal_data *)signal_data;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (signal != S_SNS_CONFIGURED &&  nssd->nsvc != the_pcu.nsvc) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DPCU, LOGL_ERROR, "Signal received of unknown NSVC\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (signal) {</span><br><span style="color: hsl(0, 100%, 40%);">-       case S_SNS_CONFIGURED:</span><br><span style="color: hsl(0, 100%, 40%);">-          the_pcu.bvc_sig_reset = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-              the_pcu.bvc_reset = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-          /* There's no NS-RESET / NS-UNBLOCK procedure on IP SNS based NS-VCs */</span><br><span style="color: hsl(0, 100%, 40%);">-             the_pcu.nsvc_unblocked = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n", the_pcu.nsvc->nsvci);</span><br><span style="color: hsl(0, 100%, 40%);">-          bvc_timeout(NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case S_NS_UNBLOCK:</span><br><span style="color: hsl(120, 100%, 40%);">+    case NS_AFF_CAUSE_RECOVERY:</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became available\n", nsp->nsei);</span><br><span>             if (!the_pcu.nsvc_unblocked) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  the_pcu.nsvc_unblocked = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                     LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                           the_pcu.nsvc->nsvci);</span><br><span>                     the_pcu.bvc_sig_reset = 0;</span><br><span>                   the_pcu.bvc_reset = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                  the_pcu.bvc_unblocked = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                    the_pcu.nsvc_unblocked = 1;</span><br><span>                  bvc_timeout(NULL);</span><br><span>           }</span><br><span>            break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case S_NS_BLOCK:</span><br><span style="color: hsl(120, 100%, 40%);">+      case NS_AFF_CAUSE_FAILURE:</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became unavailable\n", nsp->nsei);</span><br><span>           if (the_pcu.nsvc_unblocked) {</span><br><span>                        the_pcu.nsvc_unblocked = 0;</span><br><span>                  osmo_timer_del(&the_pcu.bvc_timer);</span><br><span>                      the_pcu.bvc_sig_reset = 0;</span><br><span>                   the_pcu.bvc_reset = 0;</span><br><span>                       the_pcu.bvc_unblocked = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                      LOGP(DPCU, LOGL_NOTICE, "NS-VC is blocked.\n");</span><br><span>            }</span><br><span>            break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case S_NS_ALIVE_EXP:</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DPCU, LOGL_NOTICE, "Tns alive expired too often, "</span><br><span style="color: hsl(0, 100%, 40%);">-                       "re-starting RESET procedure\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             gprs_ns_reconnect(nssd->nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DPCU, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "NS: %s Unknown prim %d from NS\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                 get_value_string(osmo_prim_op_names, nsp->oph.operation),</span><br><span style="color: hsl(120, 100%, 40%);">+                  nsp->oph.primitive);</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%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* called by the ns layer */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_gprs_ns2_prim *nsp;</span><br><span style="color: hsl(120, 100%, 40%);">+       int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (oph->sap != SAP_NS)</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%);">+   nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (oph->operation != PRIM_OP_INDICATION) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DPCU, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              get_value_string(osmo_prim_op_names, oph->operation),</span><br><span style="color: hsl(120, 100%, 40%);">+              oph->operation);</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 style="color: hsl(120, 100%, 40%);">+   switch (oph->primitive) {</span><br><span style="color: hsl(120, 100%, 40%);">+  case PRIM_NS_UNIT_DATA:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* hand the message into the BSSGP implementation */</span><br><span style="color: hsl(120, 100%, 40%);">+          /* add required msg fields for Gb layer */</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_bssgph(oph->msg) = oph->msg->l3h;</span><br><span style="color: hsl(120, 100%, 40%);">+               msgb_bvci(oph->msg) = nsp->bvci;</span><br><span style="color: hsl(120, 100%, 40%);">+                msgb_nsei(oph->msg) = nsp->nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = gprs_bssgp_pcu_rcvmsg(oph->msg);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case PRIM_NS_STATUS:</span><br><span style="color: hsl(120, 100%, 40%);">+          gprs_ns_prim_status_cb(nsp);</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DPCU, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "NS: %s Unknown prim %d from NS\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                 get_value_string(osmo_prim_op_names, oph->operation),</span><br><span style="color: hsl(120, 100%, 40%);">+              oph->primitive);</span><br><span>             break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     return rc;</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%);">+/* called by the bssgp layer to send NS PDUs */</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_bssgp_send_cb(void *ctx, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gprs_ns2_inst *nsi = (struct gprs_ns2_inst *) ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_gprs_ns2_prim nsp = {};</span><br><span style="color: hsl(120, 100%, 40%);">+   nsp.nsei = msgb_nsei(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+    nsp.bvci = msgb_bvci(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,</span><br><span style="color: hsl(120, 100%, 40%);">+                       PRIM_OP_REQUEST, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+        return gprs_ns2_recv_prim(nsi, &nsp.oph);</span><br><span> }</span><br><span> </span><br><span> static unsigned count_pdch(const struct gprs_rlcmac_bts *bts)</span><br><span>@@ -904,77 +920,65 @@</span><br><span>      osmo_timer_schedule(&the_pcu.bvc_timer, the_pcu.bts->fc_interval, 0);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int gprs_ns_reconnect(struct gprs_nsvc *nsvc)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gprs_nsvc *nsvc2;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    if (nsvc != the_pcu.nsvc) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DBSSGP, LOGL_ERROR, "NSVC is invalid\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                return -EBADF;</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_nsvc_create_and_connect(</span><br><span style="color: hsl(120, 100%, 40%);">+             struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+          struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn,</span><br><span style="color: hsl(120, 100%, 40%);">+              uint16_t nsei, uint16_t nsvci)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_ns2_vc *nsvc;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gprs_ns2_vc_bind *bind;</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = gprs_ns2_ip_bind(bts->nsi, local, 0, &bind);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              gprs_ns2_free(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+           return 1;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (the_pcu.bts->gb_dialect_sns)</span><br><span style="color: hsl(0, 100%, 40%);">-             nsvc2 = gprs_ns_nsip_connect_sns(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);</span><br><span style="color: hsl(0, 100%, 40%);">-  else</span><br><span style="color: hsl(0, 100%, 40%);">-            nsvc2 = gprs_ns_nsip_connect(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!nsvc2) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGP(DBSSGP, LOGL_ERROR, "Failed to reconnect NSVC\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               return -EIO;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->nse = gprs_ns2_nse_by_nsei(bts->nsi, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!bts->nse)</span><br><span style="color: hsl(120, 100%, 40%);">+             bts->nse = gprs_ns2_create_nse(bts->nsi, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!bts->nse) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</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%);">+   bts->nsei = nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (bts->gb_dialect_sns) {</span><br><span style="color: hsl(120, 100%, 40%);">+         rc = gprs_ns2_ip_connect_sns(bind, sgsn, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              nsvc = gprs_ns2_ip_connect2(bind, sgsn, nsei, nsvci);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!nsvc)</span><br><span style="color: hsl(120, 100%, 40%);">+                    rc = -1;</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 (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* TODO: Could not connect */</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</span><br><span>    }</span><br><span> </span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* create BSSGP/NS layer instances */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint16_t local_port, uint32_t sgsn_ip,</span><br><span style="color: hsl(0, 100%, 40%);">-  uint16_t sgsn_port, uint16_t nsei, uint16_t nsvci, uint16_t bvci,</span><br><span style="color: hsl(0, 100%, 40%);">-       uint16_t mcc, uint16_t mnc, bool mnc_3_digits, uint16_t lac, uint16_t rac,</span><br><span style="color: hsl(0, 100%, 40%);">-      uint16_t cell_id)</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_bssgp_pcu *gprs_bssgp_init(</span><br><span style="color: hsl(120, 100%, 40%);">+            struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint16_t nsei, uint16_t bvci,</span><br><span style="color: hsl(120, 100%, 40%);">+         uint16_t mcc, uint16_t mnc, bool mnc_3_digits,</span><br><span style="color: hsl(120, 100%, 40%);">+                uint16_t lac, uint16_t rac, uint16_t cell_id)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct sockaddr_in dest;</span><br><span style="color: hsl(0, 100%, 40%);">-        int rc;</span><br><span> </span><br><span>  /* if already created... return the current address */</span><br><span>       if (the_pcu.bctx)</span><br><span>            return &the_pcu;</span><br><span> </span><br><span>     the_pcu.bts = bts;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* don't specify remote IP/port if SNS dialect is in use; Doing so would</span><br><span style="color: hsl(0, 100%, 40%);">-     * issue a connect() on the socket, which prevents us to dynamically communicate</span><br><span style="color: hsl(0, 100%, 40%);">-         * with any number of IP-SNS endpoints on the SGSN side */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!bts->gb_dialect_sns) {</span><br><span style="color: hsl(0, 100%, 40%);">-          bssgp_nsi->nsip.remote_port = sgsn_port;</span><br><span style="color: hsl(0, 100%, 40%);">-             bssgp_nsi->nsip.remote_ip = sgsn_ip;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       bssgp_nsi->nsip.local_port = local_port;</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = gprs_ns_nsip_listen(bssgp_nsi);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                gprs_ns_close(bssgp_nsi);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       dest.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-      dest.sin_port = htons(sgsn_port);</span><br><span style="color: hsl(0, 100%, 40%);">-       dest.sin_addr.s_addr = htonl(sgsn_ip);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (bts->gb_dialect_sns)</span><br><span style="color: hsl(0, 100%, 40%);">-             the_pcu.nsvc = gprs_ns_nsip_connect_sns(bssgp_nsi, &dest, nsei, nsvci);</span><br><span style="color: hsl(0, 100%, 40%);">-     else</span><br><span style="color: hsl(0, 100%, 40%);">-            the_pcu.nsvc = gprs_ns_nsip_connect(bssgp_nsi, &dest, nsei, nsvci);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!the_pcu.nsvc) {</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSVCt\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         gprs_ns_close(bssgp_nsi);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    the_pcu.bctx = btsctx_alloc(bvci, nsei);</span><br><span>     if (!the_pcu.bctx) {</span><br><span>                 LOGP(DBSSGP, LOGL_ERROR, "Failed to create BSSGP context\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         the_pcu.nsvc = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-            gprs_ns_close(bssgp_nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+             the_pcu.bts->nse = NULL;</span><br><span>          return NULL;</span><br><span>         }</span><br><span>    the_pcu.bctx->ra_id.mcc = spoof_mcc ? : mcc;</span><br><span>@@ -989,37 +993,27 @@</span><br><span>      the_pcu.bctx->ra_id.rac = rac;</span><br><span>    the_pcu.bctx->cell_id = cell_id;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- osmo_signal_register_handler(SS_L_NS, nsvc_signal_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    osmo_timer_setup(&the_pcu.bvc_timer, bvc_timeout, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_timer_setup(&the_pcu.bvc_timer, bvc_timeout, bts);</span><br><span> </span><br><span>      return &the_pcu;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_bssgp_destroy(void)</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_bssgp_destroy(struct gprs_rlcmac_bts *bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_ns_inst *nsi = bssgp_nsi;</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!nsi)</span><br><span style="color: hsl(0, 100%, 40%);">-               return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- bssgp_nsi = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    osmo_timer_del(&the_pcu.bvc_timer);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     osmo_signal_unregister_handler(SS_L_NS, nsvc_signal_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  the_pcu.nsvc = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>         /* FIXME: blocking... */</span><br><span>     the_pcu.nsvc_unblocked = 0;</span><br><span>  the_pcu.bvc_sig_reset = 0;</span><br><span>   the_pcu.bvc_reset = 0;</span><br><span>       the_pcu.bvc_unblocked = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_ns_destroy(nsi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        bssgp_bvc_ctx_free(the_pcu.bctx);</span><br><span>    the_pcu.bctx = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        gprs_ns2_free(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->nsi = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->nse = NULL;</span><br><span> }</span><br><span> </span><br><span> struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void)</span><br><span>diff --git a/src/gprs_bssgp_pcu.h b/src/gprs_bssgp_pcu.h</span><br><span>index 2ceef60..6341161 100644</span><br><span>--- a/src/gprs_bssgp_pcu.h</span><br><span>+++ b/src/gprs_bssgp_pcu.h</span><br><span>@@ -28,7 +28,7 @@</span><br><span> #include <osmocom/core/logging.h></span><br><span> #include <osmocom/core/signal.h></span><br><span> #include <osmocom/core/application.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gprs/gprs_ns.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_ns2.h></span><br><span> #include <osmocom/gprs/gprs_bssgp.h></span><br><span> #include <osmocom/gprs/gprs_bssgp_bss.h></span><br><span> #include <osmocom/gprs/gprs_msgb.h></span><br><span>@@ -45,7 +45,6 @@</span><br><span> #define IE_LLC_PDU 14</span><br><span> </span><br><span> struct gprs_bssgp_pcu {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gprs_nsvc *nsvc;</span><br><span>      struct bssgp_bvc_ctx *bctx;</span><br><span> </span><br><span>      struct gprs_rlcmac_bts *bts;</span><br><span>@@ -76,16 +75,21 @@</span><br><span>                           struct tlv_parsed *tp);</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(0, 100%, 40%);">-              uint16_t local_port,</span><br><span style="color: hsl(0, 100%, 40%);">-            uint32_t sgsn_ip, uint16_t sgsn_port, uint16_t nsei,</span><br><span style="color: hsl(0, 100%, 40%);">-            uint16_t nsvci, uint16_t bvci, uint16_t mcc, uint16_t mnc, bool mnc_3_digits,</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_bssgp_pcu *gprs_bssgp_init(</span><br><span style="color: hsl(120, 100%, 40%);">+                struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint16_t nsei, uint16_t bvci,</span><br><span style="color: hsl(120, 100%, 40%);">+         uint16_t mcc, uint16_t mnc, bool mnc_3_digits,</span><br><span>               uint16_t lac, uint16_t rac, uint16_t cell_id);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,</span><br><span style="color: hsl(0, 100%, 40%);">-         struct msgb *msg, uint16_t bvci);</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_nsvc_create_and_connect(</span><br><span style="color: hsl(120, 100%, 40%);">+           struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+          struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn,</span><br><span style="color: hsl(120, 100%, 40%);">+              uint16_t nsei, uint16_t nsvci);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_bssgp_destroy(void);</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_bssgp_send_cb(void *ctx, struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void gprs_bssgp_destroy(struct gprs_rlcmac_bts *bts);</span><br><span> </span><br><span> struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void);</span><br><span> </span><br><span>diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp</span><br><span>index 8d3d26f..c9beff0 100644</span><br><span>--- a/src/osmobts_sock.cpp</span><br><span>+++ b/src/osmobts_sock.cpp</span><br><span>@@ -121,7 +121,7 @@</span><br><span>          gprs_rlcmac_tbf::free_all(&bts->trx[trx]);</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_bssgp_destroy();</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_bssgp_destroy(bts);</span><br><span>     exit(0);</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp</span><br><span>index 535fb70..b58e2ff 100644</span><br><span>--- a/src/pcu_l1_if.cpp</span><br><span>+++ b/src/pcu_l1_if.cpp</span><br><span>@@ -36,6 +36,7 @@</span><br><span> #include <osmocom/core/gsmtap_util.h></span><br><span> #include <osmocom/core/gsmtap.h></span><br><span> #include <osmocom/core/bitvec.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/sockaddr_str.h></span><br><span> #include <osmocom/core/logging.h></span><br><span> #include <osmocom/core/utils.h></span><br><span> #include <osmocom/gsm/l1sap.h></span><br><span>@@ -491,8 +492,9 @@</span><br><span> {</span><br><span>       struct gprs_rlcmac_bts *bts = bts_main_data();</span><br><span>       struct gprs_bssgp_pcu *pcu;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct in_addr ia;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_sockaddr local_sockaddr = {}, remote_sockaddr = {};</span><br><span>      int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   int good_nsvc = 0;</span><br><span>   unsigned int trx_nr, ts_nr;</span><br><span>  int i;</span><br><span> </span><br><span>@@ -517,7 +519,7 @@</span><br><span>                     for (ts_nr = 0; ts_nr < ARRAY_SIZE(bts->trx[0].pdch); ts_nr++)</span><br><span>                                 bts->trx[trx_nr].pdch[ts_nr].free_resources();</span><br><span>            }</span><br><span style="color: hsl(0, 100%, 40%);">-               gprs_bssgp_destroy();</span><br><span style="color: hsl(120, 100%, 40%);">+         gprs_bssgp_destroy(bts);</span><br><span>             exit(0);</span><br><span>     }</span><br><span>    LOGP(DL1IF, LOGL_INFO, "BTS available\n");</span><br><span>@@ -566,30 +568,65 @@</span><br><span>         }</span><br><span>    LOGP(DL1IF, LOGL_DEBUG, " initial_cs=%d\n", info_ind->initial_cs);</span><br><span>      LOGP(DL1IF, LOGL_DEBUG, " initial_mcs=%d\n", info_ind->initial_mcs);</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGP(DL1IF, LOGL_DEBUG, " nsvci=%d\n", info_ind->nsvci[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-        LOGP(DL1IF, LOGL_DEBUG, " local_port=%d\n", info_ind->local_port[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-      LOGP(DL1IF, LOGL_DEBUG, " remote_port=%d\n", info_ind->remote_port[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-    ia.s_addr = info_ind->remote_ip[0].v4.s_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-        LOGP(DL1IF, LOGL_DEBUG, " remote_ip=%s\n", inet_ntoa(ia));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        switch (info_ind->address_type[0]) {</span><br><span style="color: hsl(0, 100%, 40%);">- case PCU_IF_ADDR_TYPE_IPV4:</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case PCU_IF_ADDR_TYPE_IPV6:</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DL1IF, LOGL_ERROR, "This PCU does not support IPv6 NSVC!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            goto bssgp_failed;</span><br><span style="color: hsl(0, 100%, 40%);">-      default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DL1IF, LOGL_ERROR, "No IPv4 NSVC given!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+   pcu = gprs_bssgp_init(</span><br><span style="color: hsl(120, 100%, 40%);">+                        bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                  info_ind->nsei, info_ind->bvci,</span><br><span style="color: hsl(120, 100%, 40%);">+                 info_ind->mcc, info_ind->mnc, info_ind->mnc_3_digits,</span><br><span style="color: hsl(120, 100%, 40%);">+                        info_ind->lac, info_ind->rac, info_ind->cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!pcu) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DL1IF, LOGL_NOTICE, "Failed to init BSSGP\n");</span><br><span>                goto bssgp_failed;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   pcu = gprs_bssgp_create_and_connect(bts, info_ind->local_port[0],</span><br><span style="color: hsl(0, 100%, 40%);">-            ntohl(info_ind->remote_ip[0].v4.s_addr), info_ind->remote_port[0],</span><br><span style="color: hsl(0, 100%, 40%);">-                info_ind->nsei, info_ind->nsvci[0], info_ind->bvci,</span><br><span style="color: hsl(0, 100%, 40%);">-            info_ind->mcc, info_ind->mnc, info_ind->mnc_3_digits, info_ind->lac, info_ind->rac,</span><br><span style="color: hsl(0, 100%, 40%);">-              info_ind->cell_id);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!pcu) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DL1IF, LOGL_NOTICE, "SGSN is not available\n");</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%);">+          struct osmo_sockaddr_str sockstr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           switch (info_ind->address_type[i]) {</span><br><span style="color: hsl(120, 100%, 40%);">+               case IPPROTO_IPIP:</span><br><span style="color: hsl(120, 100%, 40%);">+                    local_sockaddr.u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+                    local_sockaddr.u.sin.sin_addr.s_addr = INADDR_ANY;</span><br><span style="color: hsl(120, 100%, 40%);">+                    local_sockaddr.u.sin.sin_port = htons(info_ind->local_port[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  remote_sockaddr.u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+                   remote_sockaddr.u.sin.sin_addr = info_ind->remote_ip[i].v4;</span><br><span style="color: hsl(120, 100%, 40%);">+                        remote_sockaddr.u.sin.sin_port = htons(info_ind->remote_port[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case IPPROTO_IPV6:</span><br><span style="color: hsl(120, 100%, 40%);">+                    local_sockaddr.u.sin6.sin6_family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+                 local_sockaddr.u.sin6.sin6_addr = in6addr_any;</span><br><span style="color: hsl(120, 100%, 40%);">+                        local_sockaddr.u.sin6.sin6_port = htons(info_ind->local_port[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        remote_sockaddr.u.sin6.sin6_family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+                        remote_sockaddr.u.sin6.sin6_addr = info_ind->remote_ip[i].v6;</span><br><span style="color: hsl(120, 100%, 40%);">+                      remote_sockaddr.u.sin6.sin6_port = htons(info_ind->remote_port[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                default:</span><br><span style="color: hsl(120, 100%, 40%);">+                      continue;</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%);">+           LOGP(DL1IF, LOGL_DEBUG, " NS%d nsvci=%d\n", i, info_ind->nsvci[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DL1IF, LOGL_DEBUG, " NS%d local_port=%d\n", i, info_ind->local_port[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DL1IF, LOGL_DEBUG, " NS%d remote_port=%d\n", i, info_ind->remote_port[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote_sockaddr.u.sas))</span><br><span style="color: hsl(120, 100%, 40%);">+                        strcpy(sockstr.ip, "invalid");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DL1IF, LOGL_DEBUG, " NS%d remote_ip=%s\n", i, sockstr.ip);</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = gprs_nsvc_create_and_connect(bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                  &local_sockaddr, &remote_sockaddr,</span><br><span style="color: hsl(120, 100%, 40%);">+                                            info_ind->nsei, info_ind->nsvci[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DL1IF, LOGL_ERROR, "Failed to create NSVC connection to %s:%d!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                          sockstr.ip, sockstr.port);</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</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%);">+           good_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%);">+   if (good_nsvc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGP(DL1IF, LOGL_ERROR, "No NSVC available to connect to the SGSN!\n");</span><br><span>            goto bssgp_failed;</span><br><span>   }</span><br><span> </span><br><span>diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp</span><br><span>index c5ff3dc..6616e11 100644</span><br><span>--- a/src/pcu_main.cpp</span><br><span>+++ b/src/pcu_main.cpp</span><br><span>@@ -38,7 +38,7 @@</span><br><span> #include "pcu_vty.h"</span><br><span> #include "coding_scheme.h"</span><br><span> #include <osmocom/gprs/gprs_bssgp.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gprs/gprs_ns.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_ns2.h></span><br><span> #include <osmocom/vty/telnet_interface.h></span><br><span> #include <osmocom/vty/command.h></span><br><span> #include <osmocom/vty/vty.h></span><br><span>@@ -267,7 +267,6 @@</span><br><span> </span><br><span>         osmo_stats_init(tall_pcu_ctx);</span><br><span>       rate_ctr_init(tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_ns_set_log_ss(DNS);</span><br><span>     bssgp_set_log_ss(DBSSGP);</span><br><span> </span><br><span>        pcu_vty_info.tall_ctx = tall_pcu_ctx;</span><br><span>@@ -289,12 +288,13 @@</span><br><span>        else</span><br><span>                 fprintf(stderr, "Failed to initialize GSMTAP for %s\n", gsmtap_addr);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bssgp_nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                exit(1);</span><br><span>     }</span><br><span style="color: hsl(0, 100%, 40%);">-       gprs_ns_vty_init(bssgp_nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+  bssgp_set_bssgp_callback(gprs_bssgp_send_cb, bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+    gprs_ns2_vty_init(bts->nsi);</span><br><span> </span><br><span>  rc = vty_read_config_file(config_file, NULL);</span><br><span>        if (rc < 0 && config_given) {</span><br><span>@@ -306,6 +306,8 @@</span><br><span>               fprintf(stderr, "No config file: '%s' Using default config.\n",</span><br><span>                    config_file);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     gprs_ns2_vty_create();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     rc = telnet_init_dynif(tall_pcu_ctx, NULL, vty_get_bind_addr(),</span><br><span>                             OSMO_VTY_PORT_PCU);</span><br><span>   if (rc < 0) {</span><br><span>diff --git a/src/pcu_vty.c b/src/pcu_vty.c</span><br><span>index 0756136..010f98d 100644</span><br><span>--- a/src/pcu_vty.c</span><br><span>+++ b/src/pcu_vty.c</span><br><span>@@ -13,6 +13,7 @@</span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/rate_ctr.h></span><br><span> #include <osmocom/pcu/pcuif_proto.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_ns2.h></span><br><span> #include "pcu_vty.h"</span><br><span> #include "gprs_rlcmac.h"</span><br><span> #include <pdch.h></span><br><span>@@ -1096,10 +1097,13 @@</span><br><span> {</span><br><span>     struct gprs_rlcmac_bts *bts = bts_main_data();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (!strcmp(argv[0], "ip-sns"))</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!strcmp(argv[0], "ip-sns")) {</span><br><span>          bts->gb_dialect_sns = true;</span><br><span style="color: hsl(0, 100%, 40%);">-  else</span><br><span style="color: hsl(120, 100%, 40%);">+          gprs_ns2_vty_force_vc_mode(true, NS2_VC_MODE_ALIVE, "gb-dialect is ip-sns");</span><br><span style="color: hsl(120, 100%, 40%);">+        } else {</span><br><span>             bts->gb_dialect_sns = false;</span><br><span style="color: hsl(120, 100%, 40%);">+               gprs_ns2_vty_force_vc_mode(false, 0, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span> </span><br><span>        return CMD_SUCCESS;</span><br><span> }</span><br><span>diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp</span><br><span>index 7f99355..9c3a212 100644</span><br><span>--- a/tests/emu/pcu_emu.cpp</span><br><span>+++ b/tests/emu/pcu_emu.cpp</span><br><span>@@ -93,15 +93,28 @@</span><br><span>                      uint32_t sgsn_ip, uint16_t sgsn_port)</span><br><span> {</span><br><span>   struct gprs_bssgp_pcu *pcu;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_sockaddr local, remote;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- pcu = gprs_bssgp_create_and_connect(bts, 0, sgsn_ip, sgsn_port,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 20, 20, 20, 901, 99, false, 1, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ local.u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+     local.u.sin.sin_addr.s_addr = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      local.u.sin.sin_port = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   remote.u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+    remote.u.sin.sin_addr.s_addr = htonl(sgsn_ip);</span><br><span style="color: hsl(120, 100%, 40%);">+        remote.u.sin.sin_port = htons(sgsn_port);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   pcu = gprs_bssgp_init(bts, 20, 20, 901, 99, false, 1, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_nsvc_create_and_connect(bts, &local, &remote,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 20, 20);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      pcu->on_unblock_ack = bvci_unblocked;</span><br><span>     pcu->on_dl_unit_data = bssgp_data;</span><br><span> }</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_bts *bts = bts_main_data();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile Emu-PCU context");</span><br><span>        if (!tall_pcu_ctx)</span><br><span>           abort();</span><br><span>@@ -109,8 +122,8 @@</span><br><span>       msgb_talloc_ctx_init(tall_pcu_ctx, 0);</span><br><span>       osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bssgp_nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, &gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!bts->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span>@@ -121,7 +134,8 @@</span><br><span>      current_test = 0;</span><br><span> </span><br><span>        init_main_bts();</span><br><span style="color: hsl(0, 100%, 40%);">-        create_and_connect_bssgp(bts_main_data(), INADDR_LOOPBACK, 23000);</span><br><span style="color: hsl(120, 100%, 40%);">+    bssgp_set_bssgp_callback(gprs_bssgp_send_cb, bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+    create_and_connect_bssgp(bts, INADDR_LOOPBACK, 23000);</span><br><span>       </span><br><span>     for (;;)</span><br><span>             osmo_select_main(0);</span><br><span>diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp</span><br><span>index b16c089..15a79d0 100644</span><br><span>--- a/tests/tbf/TbfTest.cpp</span><br><span>+++ b/tests/tbf/TbfTest.cpp</span><br><span>@@ -470,15 +470,15 @@</span><br><span> </span><br><span>    fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bssgp_nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+     bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts = the_bts.bts_data();</span><br><span>    setup_bts(&the_bts, ts_no);</span><br><span style="color: hsl(0, 100%, 40%);">- gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 1234, 1234, 1234, 1, 1, false, 0, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);</span><br><span> </span><br><span>  for (i = 0; i < 1024; i++) {</span><br><span>              uint32_t tlli = 0xc0000000 + i;</span><br><span>@@ -497,7 +497,7 @@</span><br><span>        OSMO_ASSERT(rc == -EBUSY);</span><br><span>   fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_bssgp_destroy();</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_bssgp_destroy(bts);</span><br><span> }</span><br><span> </span><br><span> static void test_tbf_dl_llc_loss()</span><br><span>@@ -514,20 +514,20 @@</span><br><span> </span><br><span>  uint8_t buf[19];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bssgp_nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+     bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span>        fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bts = the_bts.bts_data();</span><br><span>    setup_bts(&the_bts, ts_no);</span><br><span>      /* keep the MS object 10 seconds */</span><br><span>  OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2030, 10, OSMO_TDEF_S) == 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 2234, 2234, 2234, 1, 1, false, 0, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);</span><br><span> </span><br><span>  /* Handle LLC frame 1 */</span><br><span>     memset(buf, 1, sizeof(buf));</span><br><span>@@ -582,7 +582,7 @@</span><br><span> </span><br><span>       fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_bssgp_destroy();</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_bssgp_destroy(bts);</span><br><span> }</span><br><span> </span><br><span> static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,</span><br><span>@@ -2165,19 +2165,19 @@</span><br><span> </span><br><span>    fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bssgp_nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+     bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts = the_bts.bts_data();</span><br><span>    setup_bts(&the_bts, ts_no);</span><br><span> </span><br><span>  /* EGPRS-only */</span><br><span>     bts->egprs_enabled = 1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 3234, 3234, 3234, 1, 1, false, 0, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);</span><br><span> </span><br><span>  /* Does not support EGPRS */</span><br><span>         rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,</span><br><span>@@ -2186,12 +2186,13 @@</span><br><span>   OSMO_ASSERT(rc == -EBUSY);</span><br><span>   fprintf(stderr, "=== end %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_bssgp_destroy();</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_bssgp_destroy(bts);</span><br><span> }</span><br><span> </span><br><span> static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,</span><br><span>                       bool free, bool end)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_rlcmac_bts *bts = dl_tbf->bts->bts_data();</span><br><span>        if (!dl_tbf) {</span><br><span>               fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);</span><br><span>                return;</span><br><span>@@ -2213,7 +2214,7 @@</span><br><span> </span><br><span>  if (end) {</span><br><span>           fprintf(stderr, "=== end %s ===\n", test);</span><br><span style="color: hsl(0, 100%, 40%);">-            gprs_bssgp_destroy();</span><br><span style="color: hsl(120, 100%, 40%);">+         gprs_bssgp_destroy(bts);</span><br><span>     }</span><br><span> }</span><br><span> </span><br><span>@@ -2228,13 +2229,13 @@</span><br><span> </span><br><span>     fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bssgp_nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+     bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts = the_bts.bts_data();</span><br><span>    setup_bts(&the_bts, ts_no);</span><br><span> </span><br><span>  bts->ws_base = 128;</span><br><span>@@ -2245,7 +2246,7 @@</span><br><span>       bts->trx[0].pdch[4].enable();</span><br><span>     bts->trx[0].pdch[5].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 4234, 4234, 4234, 1, 1, false, 0, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);</span><br><span> </span><br><span>  /* Does no support EGPRS */</span><br><span>  ms = the_bts.ms_alloc(ms_class, 0);</span><br><span>@@ -2274,13 +2275,13 @@</span><br><span> </span><br><span>    fprintf(stderr, "=== start %s ===\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bssgp_nsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+     bts = the_bts.bts_data();</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts->nsi) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");</span><br><span>                abort();</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   bts = the_bts.bts_data();</span><br><span>    setup_bts(&the_bts, ts_no);</span><br><span> </span><br><span>  bts->ws_base = 128;</span><br><span>@@ -2291,7 +2292,7 @@</span><br><span>       bts->trx[0].pdch[4].enable();</span><br><span>     bts->trx[0].pdch[5].enable();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 5234, 5234, 5234, 1, 1, false, 0, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);</span><br><span> </span><br><span>  /* EGPRS-only */</span><br><span>     bts->egprs_enabled = 1;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/20271">change 20271</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/osmo-pcu/+/20271"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ib389925cf5c9f18951af6242c31ea70476218e9a </div>
<div style="display:none"> Gerrit-Change-Number: 20271 </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>