aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2020-07-26 22:12:32 +0200
committerAlexander Couzens <lynxis@fe80.eu>2020-08-21 18:19:04 +0200
commit619ce0b002690b4251b84767f7db075973cfaea5 (patch)
tree79213f868448389465a2f37dca044f26432b81e6
parentb75c27febdfaf1020f4a55d55646ec5c10b2050a (diff)
WIP
-rw-r--r--src/bts.h5
-rw-r--r--src/gprs_bssgp_pcu.cpp115
-rw-r--r--src/gprs_bssgp_pcu.h18
-rw-r--r--src/osmobts_sock.cpp2
-rw-r--r--src/pcu_l1_if.cpp22
-rw-r--r--src/pcu_main.cpp13
-rw-r--r--tests/emu/pcu_emu.cpp20
7 files changed, 116 insertions, 79 deletions
diff --git a/src/bts.h b/src/bts.h
index edccc280..478cb04c 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -174,6 +174,11 @@ struct gprs_rlcmac_bts {
* more than one message, because they get sent so rarely. */
struct msgb *app_info;
uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */
+
+ struct gprs_ns2_inst *nsi;
+ /* main nsei */
+ struct gprs_ns2_nse *nse;
+ uint16_t nsei;
};
enum {
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index a4bcff31..f214db9f 100644
--- a/src/gprs_bssgp_pcu.cpp
+++ b/src/gprs_bssgp_pcu.cpp
@@ -549,7 +549,7 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
return 0;
}
-int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci)
+int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct msgb *msg, uint16_t nsei, uint16_t bvci)
{
int rc = 0;
switch (event) {
@@ -569,13 +569,14 @@ int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb
static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
- struct ns_signal_data *nssd;
+ struct gprs_rlcmac_bts *bts = (struct gprs_rlcmac_bts *) handler_data;
+ struct gprs_ns2_signal_data *nssd;
if (subsys != SS_L_NS)
return -EINVAL;
- nssd = (struct ns_signal_data *)signal_data;
- if (signal != S_SNS_CONFIGURED && nssd->nsvc != the_pcu.nsvc) {
+ nssd = (struct gprs_ns2_signal_data *)signal_data;
+ if (signal != S_SNS_CONFIGURED && nssd->nsei != the_pcu.bts->nsei) {
LOGP(DPCU, LOGL_ERROR, "Signal received of unknown NSVC\n");
return -EINVAL;
}
@@ -586,14 +587,14 @@ static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
the_pcu.bvc_reset = 0;
/* There's no NS-RESET / NS-UNBLOCK procedure on IP SNS based NS-VCs */
the_pcu.nsvc_unblocked = 1;
- LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n", the_pcu.nsvc->nsvci);
+ LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d is configured.\n", nssd->nsei);
bvc_timeout(NULL);
break;
case S_NS_UNBLOCK:
if (!the_pcu.nsvc_unblocked) {
the_pcu.nsvc_unblocked = 1;
- LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n",
- the_pcu.nsvc->nsvci);
+ LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d is unblocked.\n",
+ the_pcu.bts->nsei);
the_pcu.bvc_sig_reset = 0;
the_pcu.bvc_reset = 0;
the_pcu.bvc_unblocked = 0;
@@ -613,7 +614,6 @@ static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
case S_NS_ALIVE_EXP:
LOGP(DPCU, LOGL_NOTICE, "Tns alive expired too often, "
"re-starting RESET procedure\n");
- gprs_ns_reconnect(nssd->nsvc);
break;
}
@@ -906,32 +906,36 @@ static void bvc_timeout(void *_priv)
static int gprs_ns_reconnect(struct gprs_nsvc *nsvc)
{
- struct gprs_nsvc *nsvc2;
- if (nsvc != the_pcu.nsvc) {
- LOGP(DBSSGP, LOGL_ERROR, "NSVC is invalid\n");
- return -EBADF;
- }
+ /* shouldn't the reconnect to be done by the fsm itself? */
+// struct gprs_nsvc *nsvc2;
- if (the_pcu.bts->gb_dialect_sns)
- nsvc2 = gprs_ns_nsip_connect_sns(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
- else
- nsvc2 = gprs_ns_nsip_connect(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
- if (!nsvc2) {
- LOGP(DBSSGP, LOGL_ERROR, "Failed to reconnect NSVC\n");
- return -EIO;
- }
+// if (nsvc != the_pcu.bts->nse) {
+// LOGP(DBSSGP, LOGL_ERROR, "NSE is invalid\n");
+// return -EBADF;
+// }
+
+// if (the_pcu.bts->gb_dialect_sns)
+// nsvc2 = gprs_ns_nsip_connect_sns(pcu_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
+// else
+// nsvc2 = gprs_ns_nsip_connect(pcu_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
+// if (!nsvc2) {
+// LOGP(DBSSGP, LOGL_ERROR, "Failed to reconnect NSVC\n");
+// return -EIO;
+// }
return 0;
}
/* create BSSGP/NS layer instances */
struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts,
- uint16_t local_port, uint32_t sgsn_ip,
- uint16_t sgsn_port, uint16_t nsei, uint16_t nsvci, uint16_t bvci,
- uint16_t mcc, uint16_t mnc, bool mnc_3_digits, uint16_t lac, uint16_t rac,
- uint16_t cell_id)
+ struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn,
+ uint16_t nsei, uint16_t nsvci, uint16_t bvci,
+ uint16_t mcc, uint16_t mnc, bool mnc_3_digits,
+ uint16_t lac, uint16_t rac, uint16_t cell_id)
{
+ struct gprs_ns2_vc *nsvc;
+ struct gprs_ns2_vc_bind *bind;
struct sockaddr_in dest;
int rc;
@@ -944,37 +948,42 @@ struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts
/* don't specify remote IP/port if SNS dialect is in use; Doing so would
* issue a connect() on the socket, which prevents us to dynamically communicate
* with any number of IP-SNS endpoints on the SGSN side */
- if (!bts->gb_dialect_sns) {
- bssgp_nsi->nsip.remote_port = sgsn_port;
- bssgp_nsi->nsip.remote_ip = sgsn_ip;
- }
- bssgp_nsi->nsip.local_port = local_port;
- rc = gprs_ns_nsip_listen(bssgp_nsi);
+ rc = gprs_ns2_ip_bind(bts->nsi, local, 0, &bind);
if (rc < 0) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n");
- gprs_ns_close(bssgp_nsi);
+ gprs_ns2_free(bts->nsi);
return NULL;
}
- dest.sin_family = AF_INET;
- dest.sin_port = htons(sgsn_port);
- dest.sin_addr.s_addr = htonl(sgsn_ip);
+ the_pcu.bts->nse = gprs_ns2_nse_by_nsei(bts->nsi, nsei);
+ if (!the_pcu.bts->nse)
+ the_pcu.bts->nse = gprs_ns2_create_nse(bts->nsi, nsei);
- if (bts->gb_dialect_sns)
- the_pcu.nsvc = gprs_ns_nsip_connect_sns(bssgp_nsi, &dest, nsei, nsvci);
- else
- the_pcu.nsvc = gprs_ns_nsip_connect(bssgp_nsi, &dest, nsei, nsvci);
- if (!the_pcu.nsvc) {
- LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSVCt\n");
- gprs_ns_close(bssgp_nsi);
+ if (!the_pcu.bts->nse) {
+ LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSE\n");
+ gprs_ns2_free(bts->nsi);
+ return NULL;
+ }
+
+ if (bts->gb_dialect_sns) {
+ rc = gprs_ns2_ip_connect_sns(bind, sgsn, nsei);
+ } else {
+ nsvc = gprs_ns2_ip_connect2(bind, sgsn, nsei, nsvci);
+ if (!nsvc)
+ rc = -1;
+ }
+
+ if (rc) {
+ /* TODO: Could not connect */
return NULL;
}
+
the_pcu.bctx = btsctx_alloc(bvci, nsei);
if (!the_pcu.bctx) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create BSSGP context\n");
- the_pcu.nsvc = NULL;
- gprs_ns_close(bssgp_nsi);
+ the_pcu.bts->nse = NULL;
+ gprs_ns2_free(bts->nsi);
return NULL;
}
the_pcu.bctx->ra_id.mcc = spoof_mcc ? : mcc;
@@ -989,37 +998,35 @@ struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts
the_pcu.bctx->ra_id.rac = rac;
the_pcu.bctx->cell_id = cell_id;
- osmo_signal_register_handler(SS_L_NS, nsvc_signal_cb, NULL);
+ osmo_signal_register_handler(SS_L_NS, nsvc_signal_cb, bts);
- osmo_timer_setup(&the_pcu.bvc_timer, bvc_timeout, NULL);
+ osmo_timer_setup(&the_pcu.bvc_timer, bvc_timeout, bts);
return &the_pcu;
}
-void gprs_bssgp_destroy(void)
+void gprs_bssgp_destroy(struct gprs_rlcmac_bts *bts)
{
- struct gprs_ns_inst *nsi = bssgp_nsi;
+ struct gprs_ns2_inst *nsi = bts->nsi;
if (!nsi)
return;
- bssgp_nsi = NULL;
-
osmo_timer_del(&the_pcu.bvc_timer);
osmo_signal_unregister_handler(SS_L_NS, nsvc_signal_cb, NULL);
- the_pcu.nsvc = NULL;
-
/* FIXME: blocking... */
the_pcu.nsvc_unblocked = 0;
the_pcu.bvc_sig_reset = 0;
the_pcu.bvc_reset = 0;
the_pcu.bvc_unblocked = 0;
- gprs_ns_destroy(nsi);
-
bssgp_bvc_ctx_free(the_pcu.bctx);
the_pcu.bctx = NULL;
+
+ gprs_ns2_free(bts->nsi);
+ bts->nsi = NULL;
+ the_pcu.bts->nse = NULL;
}
struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void)
diff --git a/src/gprs_bssgp_pcu.h b/src/gprs_bssgp_pcu.h
index 2ceef609..94fccfef 100644
--- a/src/gprs_bssgp_pcu.h
+++ b/src/gprs_bssgp_pcu.h
@@ -28,7 +28,7 @@ extern "C" {
#include <osmocom/core/logging.h>
#include <osmocom/core/signal.h>
#include <osmocom/core/application.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gprs/gprs_msgb.h>
@@ -45,7 +45,6 @@ struct bssgp_bvc_ctx *btsctx_alloc(uint16_t bvci, uint16_t nsei);
#define IE_LLC_PDU 14
struct gprs_bssgp_pcu {
- struct gprs_nsvc *nsvc;
struct bssgp_bvc_ctx *bctx;
struct gprs_rlcmac_bts *bts;
@@ -77,15 +76,16 @@ struct gprs_bssgp_pcu {
};
struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts,
- uint16_t local_port,
- uint32_t sgsn_ip, uint16_t sgsn_port, uint16_t nsei,
- uint16_t nsvci, uint16_t bvci, uint16_t mcc, uint16_t mnc, bool mnc_3_digits,
- uint16_t lac, uint16_t rac, uint16_t cell_id);
+ struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn,
+ uint16_t nsei, uint16_t nsvci, uint16_t bvci,
+ uint16_t mcc, uint16_t mnc, bool mnc_3_digits,
+ uint16_t lac, uint16_t rac, uint16_t cell_id);
-int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
- struct msgb *msg, uint16_t bvci);
-void gprs_bssgp_destroy(void);
+int gprs_bssgp_ns_cb(enum gprs_ns_evt event, struct msgb *msg,
+ uint16_t nsei, uint16_t bvci);
+
+void gprs_bssgp_destroy(struct gprs_rlcmac_bts *bts);
struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void);
diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp
index 8d3d26fc..c9beff05 100644
--- a/src/osmobts_sock.cpp
+++ b/src/osmobts_sock.cpp
@@ -121,7 +121,7 @@ for the reset. */
gprs_rlcmac_tbf::free_all(&bts->trx[trx]);
}
- gprs_bssgp_destroy();
+ gprs_bssgp_destroy(bts);
exit(0);
}
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 7fa82fb5..7911b6c9 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -490,6 +490,7 @@ static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind)
struct gprs_rlcmac_bts *bts = bts_main_data();
struct gprs_bssgp_pcu *pcu;
struct gprs_rlcmac_pdch *pdch;
+ struct osmo_sockaddr local_sockaddr, remote_sockaddr;
struct in_addr ia;
int rc = 0;
unsigned int trx, ts;
@@ -516,7 +517,7 @@ bssgp_failed:
for (ts = 0; ts < ARRAY_SIZE(bts->trx[0].pdch); ts++)
bts->trx[trx].pdch[ts].free_resources();
}
- gprs_bssgp_destroy();
+ gprs_bssgp_destroy(bts);
exit(0);
}
LOGP(DL1IF, LOGL_INFO, "BTS available\n");
@@ -571,11 +572,20 @@ bssgp_failed:
ia.s_addr = htonl(info_ind->remote_ip[0]);
LOGP(DL1IF, LOGL_DEBUG, " remote_ip=%s\n", inet_ntoa(ia));
- pcu = gprs_bssgp_create_and_connect(bts, info_ind->local_port[0],
- info_ind->remote_ip[0], info_ind->remote_port[0],
- info_ind->nsei, info_ind->nsvci[0], info_ind->bvci,
- info_ind->mcc, info_ind->mnc, info_ind->mnc_3_digits, info_ind->lac, info_ind->rac,
- info_ind->cell_id);
+ local_sockaddr.u.sin.sin_family = AF_INET;
+ local_sockaddr.u.sin.sin_addr.s_addr = htonl(0);
+ local_sockaddr.u.sin.sin_port = htons(info_ind->local_port[0]);
+
+ remote_sockaddr.u.sin.sin_family = AF_INET;
+ remote_sockaddr.u.sin.sin_addr.s_addr = htonl(info_ind->remote_ip[0]);
+ remote_sockaddr.u.sin.sin_port = htons(info_ind->remote_port[0]);
+
+ pcu = gprs_bssgp_create_and_connect(
+ bts,
+ &local_sockaddr, &remote_sockaddr,
+ info_ind->nsei, info_ind->nsvci[0], info_ind->bvci,
+ info_ind->mcc, info_ind->mnc, info_ind->mnc_3_digits,
+ info_ind->lac, info_ind->rac, info_ind->cell_id);
if (!pcu) {
LOGP(DL1IF, LOGL_NOTICE, "SGSN not available\n");
goto bssgp_failed;
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index c5ff3dc3..b84537bc 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -38,7 +38,7 @@ extern "C" {
#include "pcu_vty.h"
#include "coding_scheme.h"
#include <osmocom/gprs/gprs_bssgp.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/vty.h>
@@ -267,7 +267,7 @@ int main(int argc, char *argv[])
osmo_stats_init(tall_pcu_ctx);
rate_ctr_init(tall_pcu_ctx);
- gprs_ns_set_log_ss(DNS);
+ gprs_ns2_set_log_ss(DNS);
bssgp_set_log_ss(DBSSGP);
pcu_vty_info.tall_ctx = tall_pcu_ctx;
@@ -289,12 +289,13 @@ int main(int argc, char *argv[])
else
fprintf(stderr, "Failed to initialize GSMTAP for %s\n", gsmtap_addr);
- bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
- if (!bssgp_nsi) {
+ bts->nsi = gprs_ns2_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
+ if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
exit(1);
}
- gprs_ns_vty_init(bssgp_nsi);
+ bssgp_set_bssgp_callback((bssgp_bvc_send*) gprs_ns2_send, bts->nsi);
+ gprs_ns2_vty_init(bts->nsi);
rc = vty_read_config_file(config_file, NULL);
if (rc < 0 && config_given) {
@@ -306,6 +307,8 @@ int main(int argc, char *argv[])
fprintf(stderr, "No config file: '%s' Using default config.\n",
config_file);
+ gprs_ns2_vty_create();
+
rc = telnet_init_dynif(tall_pcu_ctx, NULL, vty_get_bind_addr(),
OSMO_VTY_PORT_PCU);
if (rc < 0) {
diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp
index 7f993551..a338078a 100644
--- a/tests/emu/pcu_emu.cpp
+++ b/tests/emu/pcu_emu.cpp
@@ -93,8 +93,17 @@ void create_and_connect_bssgp(struct gprs_rlcmac_bts *bts,
uint32_t sgsn_ip, uint16_t sgsn_port)
{
struct gprs_bssgp_pcu *pcu;
+ struct osmo_sockaddr local, remote;
- pcu = gprs_bssgp_create_and_connect(bts, 0, sgsn_ip, sgsn_port,
+ local.u.sin.sin_family = AF_INET;
+ local.u.sin.sin_addr.s_addr = 0;
+ local.u.sin.sin_port = 0;
+
+ remote.u.sin.sin_family = AF_INET;
+ remote.u.sin.sin_addr.s_addr = htonl(sgsn_ip);
+ remote.u.sin.sin_port = htons(sgsn_port);
+
+ pcu = gprs_bssgp_create_and_connect(bts, &local, &remote,
20, 20, 20, 901, 99, false, 1, 0, 0);
pcu->on_unblock_ack = bvci_unblocked;
pcu->on_dl_unit_data = bssgp_data;
@@ -102,6 +111,8 @@ void create_and_connect_bssgp(struct gprs_rlcmac_bts *bts,
int main(int argc, char **argv)
{
+ struct gprs_rlcmac_bts *bts = bts_main_data();
+
tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile Emu-PCU context");
if (!tall_pcu_ctx)
abort();
@@ -109,8 +120,8 @@ int main(int argc, char **argv)
msgb_talloc_ctx_init(tall_pcu_ctx, 0);
osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
- bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
- if (!bssgp_nsi) {
+ bts->nsi = gprs_ns2_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
+ if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
abort();
}
@@ -121,7 +132,8 @@ int main(int argc, char **argv)
current_test = 0;
init_main_bts();
- create_and_connect_bssgp(bts_main_data(), INADDR_LOOPBACK, 23000);
+ bssgp_set_bssgp_callback((bssgp_bvc_send*) gprs_ns2_send, bts->nsi);
+ create_and_connect_bssgp(bts, INADDR_LOOPBACK, 23000);
for (;;)
osmo_select_main(0);