aboutsummaryrefslogtreecommitdiffstats
path: root/src/pcu_l1_if.cpp
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2020-10-12 02:27:22 +0200
committerlaforge <laforge@osmocom.org>2020-10-13 08:45:30 +0000
commit5bece2a0ed87afc708ddd4d58fab5ab840c332cf (patch)
treef9d92c152074af70992de900cd4832a0deb9018f /src/pcu_l1_if.cpp
parent3839605ec9a0878f825278d1c4e57b2b1b63e9a8 (diff)
Rework NS configuration over the info indication
Add support of the second NSVC in the info indication. Add support to update a previous NS configuration. Allow to update of a NS-VC while the NSE is still available over the second. Depends-on: I917f25ebd1239eae5855d973ced15b93731e33a0 (libosmocore) Depends-on: I3a0cd305fd73b3cb9ec70246ec15ac70b83e57f2 (libosmocore) Depends-on: I5a2bb95d05d06d909347e2fb084a446ead888cb3 (libosmocore) Depends-on: I54f110acc3acccb362f6e554324d08cc42b7c328 (libosmocore) Depends-on: Ia00753a64b7622a0864341f51ea49b6963543755 (libosmocore) Depends-on: Ic8f6f8aca10da23a18fab8870be7806065a34b47 (libosmocore) Depends-on: I5f67e6a9bf4cb322bd169061fee0a528012ed54d (libosmocore) Change-Id: I589ebaa2a2b7de55b7e4e975d8fd6412dd5f214b
Diffstat (limited to 'src/pcu_l1_if.cpp')
-rw-r--r--src/pcu_l1_if.cpp105
1 files changed, 56 insertions, 49 deletions
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 99d4a584..4491c4ec 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -39,6 +39,7 @@ extern "C" {
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/l1sap.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
}
@@ -488,12 +489,64 @@ static int pcu_rx_rach_ind(const struct gsm_pcu_if_rach_ind *rach_ind)
return rc;
}
+static int pcu_info_ind_ns(struct gprs_rlcmac_bts *bts,
+ const struct gsm_pcu_if_info_ind *info_ind)
+{
+ struct osmo_sockaddr remote[PCU_IF_NUM_NSVC] = { };
+ struct osmo_sockaddr local[PCU_IF_NUM_NSVC] = { };
+ uint16_t nsvci[PCU_IF_NUM_NSVC] = { };
+ uint16_t valid = 0;
+
+ for (unsigned int i = 0; i < PCU_IF_NUM_NSVC; i++) {
+ struct osmo_sockaddr_str sockstr;
+
+ switch (info_ind->address_type[i]) {
+ case PCU_IF_ADDR_TYPE_IPV4:
+ local[i].u.sin.sin_family = AF_INET;
+ local[i].u.sin.sin_addr.s_addr = INADDR_ANY;
+ local[i].u.sin.sin_port = htons(info_ind->local_port[i]);
+
+ remote[i].u.sin.sin_family = AF_INET;
+ remote[i].u.sin.sin_addr = info_ind->remote_ip[i].v4;
+ remote[i].u.sin.sin_port = htons(info_ind->remote_port[i]);
+ break;
+ case PCU_IF_ADDR_TYPE_IPV6:
+ local[i].u.sin6.sin6_family = AF_INET6;
+ local[i].u.sin6.sin6_addr = in6addr_any;
+ local[i].u.sin6.sin6_port = htons(info_ind->local_port[i]);
+
+ remote[i].u.sin6.sin6_family = AF_INET6;
+ remote[i].u.sin6.sin6_addr = info_ind->remote_ip[i].v6;
+ remote[i].u.sin6.sin6_port = htons(info_ind->remote_port[i]);
+ break;
+ default:
+ continue;
+ }
+ nsvci[i] = info_ind->nsvci[i];
+
+ LOGP(DL1IF, LOGL_DEBUG, " NS%u nsvci=%u\n", i, nsvci[i]);
+ if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote[i].u.sas))
+ strcpy(sockstr.ip, "invalid");
+
+ LOGP(DL1IF, LOGL_DEBUG, " NS%u address: r=%s:%u<->l=NULL:%u\n",
+ i, sockstr.ip, sockstr.port, info_ind->local_port[i]);
+
+ valid |= 1 << i;
+ }
+
+ if (valid == 0) {
+ LOGP(DL1IF, LOGL_ERROR, "No NSVC available to connect to the SGSN!\n");
+ return -EINVAL;
+ }
+
+ return gprs_ns_config(bts, info_ind->nsei, local, remote, nsvci, valid);
+}
+
static int pcu_rx_info_ind(const struct gsm_pcu_if_info_ind *info_ind)
{
struct gprs_rlcmac_bts *bts = bts_main_data();
struct gprs_bssgp_pcu *pcu;
int rc = 0;
- int good_nsvc = 0;
unsigned int trx_nr, ts_nr;
int i;
@@ -578,54 +631,8 @@ bssgp_failed:
goto bssgp_failed;
}
- for (unsigned int i = 0; i < ARRAY_SIZE(info_ind->nsvci); i++) {
- struct osmo_sockaddr remote_sockaddr = { };
- struct osmo_sockaddr local_sockaddr = { };
- struct osmo_sockaddr_str sockstr;
-
- switch (info_ind->address_type[i]) {
- case PCU_IF_ADDR_TYPE_IPV4:
- local_sockaddr.u.sin.sin_family = AF_INET;
- local_sockaddr.u.sin.sin_addr.s_addr = INADDR_ANY;
- local_sockaddr.u.sin.sin_port = htons(info_ind->local_port[i]);
-
- remote_sockaddr.u.sin.sin_family = AF_INET;
- remote_sockaddr.u.sin.sin_addr = info_ind->remote_ip[i].v4;
- remote_sockaddr.u.sin.sin_port = htons(info_ind->remote_port[i]);
- break;
- case PCU_IF_ADDR_TYPE_IPV6:
- local_sockaddr.u.sin6.sin6_family = AF_INET6;
- local_sockaddr.u.sin6.sin6_addr = in6addr_any;
- local_sockaddr.u.sin6.sin6_port = htons(info_ind->local_port[i]);
-
- remote_sockaddr.u.sin6.sin6_family = AF_INET6;
- remote_sockaddr.u.sin6.sin6_addr = info_ind->remote_ip[i].v6;
- remote_sockaddr.u.sin6.sin6_port = htons(info_ind->remote_port[i]);
- break;
- default:
- continue;
- }
-
- LOGP(DL1IF, LOGL_DEBUG, " NS%u nsvci=%u\n", i, info_ind->nsvci[i]);
-
- if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote_sockaddr.u.sas))
- strcpy(sockstr.ip, "invalid");
-
- LOGP(DL1IF, LOGL_DEBUG, " NS%u address: r=%s:%u<->l=NULL:%u\n",
- i, sockstr.ip, sockstr.port, info_ind->local_port[i]);
- rc = gprs_nsvc_create_and_connect(bts,
- &local_sockaddr, &remote_sockaddr,
- info_ind->nsei, info_ind->nsvci[i]);
- if (rc) {
- LOGP(DL1IF, LOGL_ERROR, "Failed to create NSVC connection to %s:%u!\n",
- sockstr.ip, sockstr.port);
- continue;
- }
-
- good_nsvc++;
- }
-
- if (good_nsvc == 0) {
+ rc = pcu_info_ind_ns(pcu->bts, info_ind);
+ if (rc < 0) {
LOGP(DL1IF, LOGL_ERROR, "No NSVC available to connect to the SGSN!\n");
goto bssgp_failed;
}