From 619ce0b002690b4251b84767f7db075973cfaea5 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Sun, 26 Jul 2020 22:12:32 +0200 Subject: WIP --- src/bts.h | 5 +++ src/gprs_bssgp_pcu.cpp | 115 ++++++++++++++++++++++++++----------------------- src/gprs_bssgp_pcu.h | 18 ++++---- src/osmobts_sock.cpp | 2 +- src/pcu_l1_if.cpp | 22 +++++++--- src/pcu_main.cpp | 13 +++--- tests/emu/pcu_emu.cpp | 20 +++++++-- 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 #include #include -#include +#include #include #include #include @@ -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 -#include +#include #include #include #include @@ -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); -- cgit v1.2.3