<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/20565">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Rework NS configuration over the info indication<br><br>Add support of the second NSVC in the info indication.<br>Add support to update a previous NS configuration.<br>Allow to update of a NS-VC while the NSE is still available over the<br>second.<br><br>Depends-on: I917f25ebd1239eae5855d973ced15b93731e33a0 (libosmocore)<br>Depends-on: I3a0cd305fd73b3cb9ec70246ec15ac70b83e57f2 (libosmocore)<br>Depends-on: I5a2bb95d05d06d909347e2fb084a446ead888cb3 (libosmocore)<br>Depends-on: I54f110acc3acccb362f6e554324d08cc42b7c328 (libosmocore)<br>Depends-on: Ia00753a64b7622a0864341f51ea49b6963543755 (libosmocore)<br>Depends-on: Ic8f6f8aca10da23a18fab8870be7806065a34b47 (libosmocore)<br>Depends-on: I5f67e6a9bf4cb322bd169061fee0a528012ed54d (libosmocore)<br>Change-Id: I589ebaa2a2b7de55b7e4e975d8fd6412dd5f214b<br>---<br>M include/osmocom/pcu/pcuif_proto.h<br>M src/gprs_bssgp_pcu.cpp<br>M src/gprs_bssgp_pcu.h<br>M src/pcu_l1_if.cpp<br>M tests/emu/pcu_emu.cpp<br>5 files changed, 212 insertions(+), 85 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/pcu/pcuif_proto.h b/include/osmocom/pcu/pcuif_proto.h</span><br><span>index 82d761d..cdd73d9 100644</span><br><span>--- a/include/osmocom/pcu/pcuif_proto.h</span><br><span>+++ b/include/osmocom/pcu/pcuif_proto.h</span><br><span>@@ -56,6 +56,8 @@</span><br><span> #define PCU_IF_ADDR_TYPE_IPV4  0x04    /* IPv4 address */</span><br><span> #define PCU_IF_ADDR_TYPE_IPV6     0x29    /* IPv6 address */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define PCU_IF_NUM_NSVC 2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum gsm_pcu_if_text_type {</span><br><span>   PCU_VERSION,</span><br><span>         PCU_OML_ALERT,</span><br><span>@@ -167,14 +169,14 @@</span><br><span>       uint8_t         initial_cs;</span><br><span>  uint8_t         initial_mcs;</span><br><span>         /* NSVC */</span><br><span style="color: hsl(0, 100%, 40%);">-      uint16_t        nsvci[2];</span><br><span style="color: hsl(0, 100%, 40%);">-       uint16_t        local_port[2];</span><br><span style="color: hsl(0, 100%, 40%);">-  uint16_t        remote_port[2];</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t         address_type[2];</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t        nsvci[PCU_IF_NUM_NSVC];</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t        local_port[PCU_IF_NUM_NSVC];</span><br><span style="color: hsl(120, 100%, 40%);">+  uint16_t        remote_port[PCU_IF_NUM_NSVC];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t         address_type[PCU_IF_NUM_NSVC];</span><br><span>       union {</span><br><span>              struct in_addr v4;</span><br><span>           struct in6_addr v6;</span><br><span style="color: hsl(0, 100%, 40%);">-     } remote_ip[2];</span><br><span style="color: hsl(120, 100%, 40%);">+       } remote_ip[PCU_IF_NUM_NSVC];</span><br><span> } __attribute__ ((packed));</span><br><span> </span><br><span> struct gsm_pcu_if_act_req {</span><br><span>diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp</span><br><span>index adf5bf3..9b6cbaa 100644</span><br><span>--- a/src/gprs_bssgp_pcu.cpp</span><br><span>+++ b/src/gprs_bssgp_pcu.cpp</span><br><span>@@ -920,44 +920,161 @@</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gprs_nsvc_create_and_connect(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(0, 100%, 40%);">-                               const struct osmo_sockaddr *local,</span><br><span style="color: hsl(0, 100%, 40%);">-                              const struct osmo_sockaddr *sgsn,</span><br><span style="color: hsl(0, 100%, 40%);">-                               uint16_t nsei, uint16_t nsvci)</span><br><span style="color: hsl(120, 100%, 40%);">+static int ns_create_nsvc(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                         uint16_t nsei,</span><br><span style="color: hsl(120, 100%, 40%);">+                        const struct osmo_sockaddr *local,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct osmo_sockaddr *remote,</span><br><span style="color: hsl(120, 100%, 40%);">+                   const uint16_t *nsvci,</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t valid)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        int i, rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t binds = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   bool nsvcs = false;</span><br><span>  struct gprs_ns2_vc *nsvc;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gprs_ns2_vc_bind *bind;</span><br><span style="color: hsl(0, 100%, 40%);">-  int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_ns2_vc_bind *bind[PCU_IF_NUM_NSVC] = { };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!valid)</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%);">+  for (i = 0; i < PCU_IF_NUM_NSVC; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!(valid & (1 << i)))</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%);">+           if (!gprs_ns2_ip_bind_by_sockaddr(bts->nsi, &local[i])) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      rc = gprs_ns2_ip_bind(bts->nsi, &local[i], 0, &bind[i]);</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 bind to %s\n", osmo_sockaddr_to_str(&local[i]));</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           binds |= 1 << i;</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 (!binds) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGP(DBSSGP, LOGL_ERROR, "Failed to bind to any NS-VC\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span> </span><br><span>        bts->nse = gprs_ns2_nse_by_nsei(bts->nsi, nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (bts->nse != NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* FIXME: we end up here on receipt of subsequent INFO.ind.</span><br><span style="color: hsl(0, 100%, 40%);">-              * What are we supposed to do? Re-establish the connection? */</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DBSSGP, LOGL_INFO, "NSE with NSEI %u is already configured, "</span><br><span style="color: hsl(0, 100%, 40%);">-                 "keeping it unchanged\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-         return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</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> </span><br><span style="color: hsl(0, 100%, 40%);">-       bts->nse = gprs_ns2_create_nse(bts->nsi, nsei);</span><br><span>        if (!bts->nse) {</span><br><span>          LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         gprs_ns2_free_binds(bts->nsi);</span><br><span>            return 1;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   rc = gprs_ns2_ip_bind(bts->nsi, local, 0, &bind);</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_ns2_free(bts->nsi);</span><br><span style="color: hsl(0, 100%, 40%);">-             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < PCU_IF_NUM_NSVC; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!(binds & (1 << i)))</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%);">+           /* FIXME: for SNS we just use the first successful NS-VC instead of all for the initial connect */</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[i], &remote[i], nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!rc)</span><br><span style="color: hsl(120, 100%, 40%);">+                              return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+                    else</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGP(DBSSGP, LOGL_ERROR, "Failed to connect to (SNS) towards SGSN %s!\n", osmo_sockaddr_to_str(&remote[i]));</span><br><span style="color: hsl(120, 100%, 40%);">+            } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      nsvc = gprs_ns2_ip_connect(bind[i], &remote[i], bts->nse, nsvci[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (nsvc)</span><br><span style="color: hsl(120, 100%, 40%);">+                             nsvcs = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                 else</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGP(DBSSGP, LOGL_ERROR, "Failed to connect to towards SGSN %s!\n", osmo_sockaddr_to_str(&remote[i]));</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (bts->gb_dialect_sns) {</span><br><span style="color: hsl(0, 100%, 40%);">-           rc = gprs_ns2_ip_connect_sns(bind, sgsn, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+       return nsvcs ? 0 : -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%);">+struct nsvc_cb {</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct osmo_sockaddr *local;</span><br><span style="color: hsl(120, 100%, 40%);">+    const struct osmo_sockaddr *remote;</span><br><span style="color: hsl(120, 100%, 40%);">+   const uint16_t *nsvci;</span><br><span style="color: hsl(120, 100%, 40%);">+        /* [in] bitmask of valid nsvc in local/remote */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t valid;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* [out] bitmask of found nsvcs */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t found;</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 int ns_conf_vc_cb(struct gprs_ns2_vc *nsvc, void *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct nsvc_cb *data = (struct nsvc_cb *) ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (unsigned int i = 0; i < PCU_IF_NUM_NSVC; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!(data->valid & (1 << i)))</span><br><span style="color: hsl(120, 100%, 40%);">+                   continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (data->found & (1 << i))</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%);">+           if (gprs_ns2_ip_vc_equal(nsvc, &data->local[i],</span><br><span style="color: hsl(120, 100%, 40%);">+                                         &data->remote[i],</span><br><span style="color: hsl(120, 100%, 40%);">+                                      data->nsvci[i])) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        data->found |= 1 << i;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Found an extra nsvc */</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGP(DBSSGP, LOGL_DEBUG, " Removing NSVC %s\n", gprs_ns2_ll_str(nsvc));</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 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%);">+int gprs_ns_config(struct gprs_rlcmac_bts *bts, uint16_t nsei,</span><br><span style="color: hsl(120, 100%, 40%);">+                   const struct osmo_sockaddr *local,</span><br><span style="color: hsl(120, 100%, 40%);">+            const struct osmo_sockaddr *remote,</span><br><span style="color: hsl(120, 100%, 40%);">+                   uint16_t *nsvci, uint16_t valid)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!bts->nse) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* there shouldn't any previous state. */</span><br><span style="color: hsl(120, 100%, 40%);">+         gprs_ns2_free_nses(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+              gprs_ns2_free_binds(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = ns_create_nsvc(bts, nsei, local, remote, nsvci, valid);</span><br><span style="color: hsl(120, 100%, 40%);">+  } else if (nsei != gprs_ns2_nse_nsei(bts->nse)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* the NSEI has changed */</span><br><span style="color: hsl(120, 100%, 40%);">+            gprs_ns2_free_nses(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+              gprs_ns2_free_binds(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = ns_create_nsvc(bts, nsei, local, remote, nsvci, valid);</span><br><span style="color: hsl(120, 100%, 40%);">+  } else if (bts->gb_dialect_sns) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* SNS: check if the initial nsvc is the same, if not recreate it */</span><br><span style="color: hsl(120, 100%, 40%);">+          const struct osmo_sockaddr *initial = gprs_ns2_nse_sns_remote(bts->nse);</span><br><span style="color: hsl(120, 100%, 40%);">+           for (unsigned int i = 0; i < PCU_IF_NUM_NSVC; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!(valid & (1 << i)))</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%);">+                   /* found the initial - everything should be fine */</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (!osmo_sockaddr_cmp(initial, &remote[i]))</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%);">+           gprs_ns2_free_nses(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+              gprs_ns2_free_binds(bts->nsi);</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = ns_create_nsvc(bts, nsei, local, remote, nsvci, valid);</span><br><span>         } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                nsvc = gprs_ns2_ip_connect2(bind, sgsn, nsei, nsvci);</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!nsvc)</span><br><span style="color: hsl(0, 100%, 40%);">-                      rc = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+              /* check if all NSVC are still the same. */</span><br><span style="color: hsl(120, 100%, 40%);">+           struct nsvc_cb data = {</span><br><span style="color: hsl(120, 100%, 40%);">+                       .local = &local[0],</span><br><span style="color: hsl(120, 100%, 40%);">+                       .remote = &remote[0],</span><br><span style="color: hsl(120, 100%, 40%);">+                     .nsvci = &nsvci[0],</span><br><span style="color: hsl(120, 100%, 40%);">+                       .valid = valid,</span><br><span style="color: hsl(120, 100%, 40%);">+                       .found = 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%);">+          /* search the current active nsvcs */</span><br><span style="color: hsl(120, 100%, 40%);">+         gprs_ns2_nse_foreach_nsvc(bts->nse, &ns_conf_vc_cb, &data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              /* we found all our valid nsvcs and might have removed all other nsvcs */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (valid == data.found)</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%);">+           /* remove all found nsvcs from the valid field */</span><br><span style="color: hsl(120, 100%, 40%);">+             valid &= ~data.found;</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = ns_create_nsvc(bts, nsei, local, remote, nsvci, valid);</span><br><span>         }</span><br><span> </span><br><span>        if (rc)</span><br><span>diff --git a/src/gprs_bssgp_pcu.h b/src/gprs_bssgp_pcu.h</span><br><span>index 078f488..db9ce9f 100644</span><br><span>--- a/src/gprs_bssgp_pcu.h</span><br><span>+++ b/src/gprs_bssgp_pcu.h</span><br><span>@@ -81,10 +81,10 @@</span><br><span>           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_nsvc_create_and_connect(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(0, 100%, 40%);">-                          const struct osmo_sockaddr *local,</span><br><span style="color: hsl(0, 100%, 40%);">-                              const struct osmo_sockaddr *sgsn,</span><br><span style="color: hsl(0, 100%, 40%);">-                               uint16_t nsei, uint16_t nsvci);</span><br><span style="color: hsl(120, 100%, 40%);">+int gprs_ns_config(struct gprs_rlcmac_bts *bts, uint16_t nsei,</span><br><span style="color: hsl(120, 100%, 40%);">+                 const struct osmo_sockaddr *local,</span><br><span style="color: hsl(120, 100%, 40%);">+            const struct osmo_sockaddr *remote,</span><br><span style="color: hsl(120, 100%, 40%);">+                   uint16_t *nsvci, uint16_t valid);</span><br><span> </span><br><span> int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx);</span><br><span> int gprs_gp_send_cb(void *ctx, struct msgb *msg);</span><br><span>diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp</span><br><span>index 99d4a58..4491c4e 100644</span><br><span>--- a/src/pcu_l1_if.cpp</span><br><span>+++ b/src/pcu_l1_if.cpp</span><br><span>@@ -39,6 +39,7 @@</span><br><span> #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 style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_ns2.h></span><br><span> #include <osmocom/gsm/l1sap.h></span><br><span> #include <osmocom/gsm/protocol/gsm_04_08.h></span><br><span> }</span><br><span>@@ -488,12 +489,64 @@</span><br><span>     return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int pcu_info_ind_ns(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const struct gsm_pcu_if_info_ind *info_ind)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_sockaddr remote[PCU_IF_NUM_NSVC] = { };</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_sockaddr local[PCU_IF_NUM_NSVC] = { };</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t nsvci[PCU_IF_NUM_NSVC] = { };</span><br><span style="color: hsl(120, 100%, 40%);">+        uint16_t valid = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (unsigned int i = 0; i < PCU_IF_NUM_NSVC; 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 PCU_IF_ADDR_TYPE_IPV4:</span><br><span style="color: hsl(120, 100%, 40%);">+                   local[i].u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+                  local[i].u.sin.sin_addr.s_addr = INADDR_ANY;</span><br><span style="color: hsl(120, 100%, 40%);">+                  local[i].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[i].u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+                 remote[i].u.sin.sin_addr = info_ind->remote_ip[i].v4;</span><br><span style="color: hsl(120, 100%, 40%);">+                      remote[i].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 PCU_IF_ADDR_TYPE_IPV6:</span><br><span style="color: hsl(120, 100%, 40%);">+                   local[i].u.sin6.sin6_family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+                       local[i].u.sin6.sin6_addr = in6addr_any;</span><br><span style="color: hsl(120, 100%, 40%);">+                      local[i].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[i].u.sin6.sin6_family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+                      remote[i].u.sin6.sin6_addr = info_ind->remote_ip[i].v6;</span><br><span style="color: hsl(120, 100%, 40%);">+                    remote[i].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%);">+             nsvci[i] = info_ind->nsvci[i];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DL1IF, LOGL_DEBUG, " NS%u nsvci=%u\n", i, nsvci[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote[i].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%u address: r=%s:%u<->l=NULL:%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    i, sockstr.ip, sockstr.port, info_ind->local_port[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              valid |= 1 << i;</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 (valid == 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 style="color: hsl(120, 100%, 40%);">+             return -EINVAL;</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 gprs_ns_config(bts, info_ind->nsei, local, remote, nsvci, valid);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int pcu_rx_info_ind(const struct gsm_pcu_if_info_ind *info_ind)</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>  int rc = 0;</span><br><span style="color: hsl(0, 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>@@ -578,54 +631,8 @@</span><br><span>            goto bssgp_failed;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   for (unsigned int i = 0; i < ARRAY_SIZE(info_ind->nsvci); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-          struct osmo_sockaddr remote_sockaddr = { };</span><br><span style="color: hsl(0, 100%, 40%);">-             struct osmo_sockaddr local_sockaddr = { };</span><br><span style="color: hsl(0, 100%, 40%);">-              struct osmo_sockaddr_str sockstr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               switch (info_ind->address_type[i]) {</span><br><span style="color: hsl(0, 100%, 40%);">-         case PCU_IF_ADDR_TYPE_IPV4:</span><br><span style="color: hsl(0, 100%, 40%);">-                     local_sockaddr.u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-                      local_sockaddr.u.sin.sin_addr.s_addr = INADDR_ANY;</span><br><span style="color: hsl(0, 100%, 40%);">-                      local_sockaddr.u.sin.sin_port = htons(info_ind->local_port[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                      remote_sockaddr.u.sin.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-                     remote_sockaddr.u.sin.sin_addr = info_ind->remote_ip[i].v4;</span><br><span style="color: hsl(0, 100%, 40%);">-                  remote_sockaddr.u.sin.sin_port = htons(info_ind->remote_port[i]);</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%);">-                     local_sockaddr.u.sin6.sin6_family = AF_INET6;</span><br><span style="color: hsl(0, 100%, 40%);">-                   local_sockaddr.u.sin6.sin6_addr = in6addr_any;</span><br><span style="color: hsl(0, 100%, 40%);">-                  local_sockaddr.u.sin6.sin6_port = htons(info_ind->local_port[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                    remote_sockaddr.u.sin6.sin6_family = AF_INET6;</span><br><span style="color: hsl(0, 100%, 40%);">-                  remote_sockaddr.u.sin6.sin6_addr = info_ind->remote_ip[i].v6;</span><br><span style="color: hsl(0, 100%, 40%);">-                        remote_sockaddr.u.sin6.sin6_port = htons(info_ind->remote_port[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        continue;</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%);">-               LOGP(DL1IF, LOGL_DEBUG, " NS%u nsvci=%u\n", i, info_ind->nsvci[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote_sockaddr.u.sas))</span><br><span style="color: hsl(0, 100%, 40%);">-                  strcpy(sockstr.ip, "invalid");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DL1IF, LOGL_DEBUG, " NS%u address: r=%s:%u<->l=NULL:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              i, sockstr.ip, sockstr.port, info_ind->local_port[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-          rc = gprs_nsvc_create_and_connect(bts,</span><br><span style="color: hsl(0, 100%, 40%);">-                                            &local_sockaddr, &remote_sockaddr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                              info_ind->nsei, info_ind->nsvci[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGP(DL1IF, LOGL_ERROR, "Failed to create NSVC connection to %s:%u!\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                            sockstr.ip, sockstr.port);</span><br><span style="color: hsl(0, 100%, 40%);">-                 continue;</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%);">-               good_nsvc++;</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%);">-       if (good_nsvc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = pcu_info_ind_ns(pcu->bts, info_ind);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc < 0) {</span><br><span>             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>diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp</span><br><span>index 98da13e..853fcb9 100644</span><br><span>--- a/tests/emu/pcu_emu.cpp</span><br><span>+++ b/tests/emu/pcu_emu.cpp</span><br><span>@@ -94,6 +94,8 @@</span><br><span> {</span><br><span>  struct gprs_bssgp_pcu *pcu;</span><br><span>  struct osmo_sockaddr local, remote;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t nsvci = 20;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint16_t nsei = 20;</span><br><span> </span><br><span>      local.u.sin.sin_family = AF_INET;</span><br><span>    local.u.sin.sin_addr.s_addr = 0;</span><br><span>@@ -104,8 +106,7 @@</span><br><span>       remote.u.sin.sin_port = htons(sgsn_port);</span><br><span> </span><br><span>        pcu = gprs_bssgp_init(bts, 20, 20, 901, 99, false, 1, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    gprs_nsvc_create_and_connect(bts, &local, &remote,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   20, 20);</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_ns_config(bts, nsei, &local, &remote, &nsvci, 1);</span><br><span> </span><br><span>       pcu->on_unblock_ack = bvci_unblocked;</span><br><span>     pcu->on_dl_unit_data = bssgp_data;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/20565">change 20565</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/+/20565"/><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: I589ebaa2a2b7de55b7e4e975d8fd6412dd5f214b </div>
<div style="display:none"> Gerrit-Change-Number: 20565 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@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>