diff options
author | Alexander Couzens <lynxis@fe80.eu> | 2020-08-22 02:55:06 +0200 |
---|---|---|
committer | Alexander Couzens <lynxis@fe80.eu> | 2020-08-22 02:55:06 +0200 |
commit | f50526e78aa09c4e6d1e38edd16f4ea63c6a0954 (patch) | |
tree | 93404d30283bdfe91307aaca33e4690912e61a40 | |
parent | 801e1b4938ec3a71e0f0a04b8d198e49d406c0f4 (diff) |
rework bssgp
Change-Id: I2ccc076cccdf256db3a6d7b8f34cf8de39bf8110
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 54 | ||||
-rw-r--r-- | src/gprs_bssgp_pcu.h | 16 | ||||
-rw-r--r-- | src/pcu_l1_if.cpp | 78 | ||||
-rw-r--r-- | tests/emu/pcu_emu.cpp | 6 |
4 files changed, 100 insertions, 54 deletions
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 154b1be4..deb16804 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -917,47 +917,33 @@ static int gprs_ns_reconnect(struct gprs_nsvc *nsvc) return 0; } -/* create BSSGP/NS layer instances */ -struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts, - 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_nsvc_create_and_connect( + struct gprs_rlcmac_bts *bts, + struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn, + uint16_t nsei, uint16_t nsvci) { struct gprs_ns2_vc *nsvc; struct gprs_ns2_vc_bind *bind; - struct sockaddr_in dest; int rc; - /* if already created... return the current address */ - if (the_pcu.bctx) - return &the_pcu; - - the_pcu.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 */ rc = gprs_ns2_ip_bind(bts->nsi, local, 0, &bind); if (rc < 0) { LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n"); gprs_ns2_free(bts->nsi); - return NULL; + return 1; } gprs_ns2_bind_set_mode(bind, NS2_VC_MODE_ALIVE); - 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); + bts->nse = gprs_ns2_nse_by_nsei(bts->nsi, nsei); + if (!bts->nse) + bts->nse = gprs_ns2_create_nse(bts->nsi, nsei); - if (!the_pcu.bts->nse) { + if (!bts->nse) { LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSE\n"); - gprs_ns2_free(bts->nsi); - return NULL; + return 1; } - the_pcu.bts->nsei = nsei; - + bts->nsei = nsei; if (bts->gb_dialect_sns) { rc = gprs_ns2_ip_connect_sns(bind, sgsn, nsei); } else { @@ -968,15 +954,28 @@ struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts if (rc) { /* TODO: Could not connect */ - return NULL; + return 1; } + return 0; +} + +struct gprs_bssgp_pcu *gprs_bssgp_init( + struct gprs_rlcmac_bts *bts, + uint16_t nsei, uint16_t bvci, + uint16_t mcc, uint16_t mnc, bool mnc_3_digits, + uint16_t lac, uint16_t rac, uint16_t cell_id) +{ + /* if already created... return the current address */ + if (the_pcu.bctx) + return &the_pcu; + + the_pcu.bts = bts; the_pcu.bctx = btsctx_alloc(bvci, nsei); if (!the_pcu.bctx) { LOGP(DBSSGP, LOGL_ERROR, "Failed to create BSSGP context\n"); the_pcu.bts->nse = NULL; - gprs_ns2_free(bts->nsi); return NULL; } the_pcu.bctx->ra_id.mcc = spoof_mcc ? : mcc; @@ -992,7 +991,6 @@ struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts the_pcu.bctx->cell_id = cell_id; osmo_signal_register_handler(SS_L_NS, nsvc_signal_cb, bts); - osmo_timer_setup(&the_pcu.bvc_timer, bvc_timeout, bts); return &the_pcu; diff --git a/src/gprs_bssgp_pcu.h b/src/gprs_bssgp_pcu.h index 1e7a4d81..872512c4 100644 --- a/src/gprs_bssgp_pcu.h +++ b/src/gprs_bssgp_pcu.h @@ -75,12 +75,16 @@ struct gprs_bssgp_pcu { struct tlv_parsed *tp); }; -struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts, - 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_bssgp_pcu *gprs_bssgp_init( + struct gprs_rlcmac_bts *bts, + uint16_t nsei, 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_nsvc_create_and_connect( + struct gprs_rlcmac_bts *bts, + struct osmo_sockaddr *local, struct osmo_sockaddr *sgsn, + uint16_t nsei, uint16_t nsvci); int gprs_bssgp_ns_cb(enum gprs_ns2_evt event, struct msgb *msg, uint16_t nsei, uint16_t bvci); diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 7911b6c9..fe610cb1 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -36,6 +36,7 @@ extern "C" { #include <osmocom/core/gsmtap_util.h> #include <osmocom/core/gsmtap.h> #include <osmocom/core/bitvec.h> +#include <osmocom/core/sockaddr_str.h> #include <osmocom/core/logging.h> #include <osmocom/core/utils.h> #include <osmocom/gsm/l1sap.h> @@ -491,8 +492,10 @@ static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind) struct gprs_bssgp_pcu *pcu; struct gprs_rlcmac_pdch *pdch; struct osmo_sockaddr local_sockaddr, remote_sockaddr; + struct osmo_sockaddr_str local; struct in_addr ia; int rc = 0; + int good_nsvc = 0; unsigned int trx, ts; int i; @@ -566,31 +569,70 @@ bssgp_failed: } LOGP(DL1IF, LOGL_DEBUG, " initial_cs=%d\n", info_ind->initial_cs); LOGP(DL1IF, LOGL_DEBUG, " initial_mcs=%d\n", info_ind->initial_mcs); - LOGP(DL1IF, LOGL_DEBUG, " nsvci=%d\n", info_ind->nsvci[0]); - LOGP(DL1IF, LOGL_DEBUG, " local_port=%d\n", info_ind->local_port[0]); - LOGP(DL1IF, LOGL_DEBUG, " remote_port=%d\n", info_ind->remote_port[0]); - ia.s_addr = htonl(info_ind->remote_ip[0]); - LOGP(DL1IF, LOGL_DEBUG, " remote_ip=%s\n", inet_ntoa(ia)); - 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( + pcu = gprs_bssgp_init( bts, - &local_sockaddr, &remote_sockaddr, - info_ind->nsei, info_ind->nsvci[0], info_ind->bvci, + info_ind->nsei, 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"); + LOGP(DL1IF, LOGL_NOTICE, "Failed to init BSSGP\n"); goto bssgp_failed; } + for (int i=0; i<2; i++) { + struct osmo_sockaddr_str sockstr; + + switch (info_ind->address_family[i]) { + case IPPROTO_IPIP: + local_sockaddr.u.sin.sin_family = AF_INET; + local_sockaddr.u.sin.sin_addr.s_addr = INADDR_ANY; + local_sockaddr.u.sin.sin_port = info_ind->local_port[i];; + + remote_sockaddr.u.sin.sin_family = AF_INET; + remote_sockaddr.u.sin.sin_addr = info_ind->remote_ip[i].ipv4; + remote_sockaddr.u.sin.sin_port = info_ind->remote_port[i]; + break; + case IPPROTO_IPV6: + local_sockaddr.u.sin6.sin6_family = AF_INET6; + local_sockaddr.u.sin6.sin6_addr = in6addr_any; + local_sockaddr.u.sin6.sin6_port = info_ind->local_port[i]; + + remote_sockaddr.u.sin6.sin6_family = AF_INET6; + remote_sockaddr.u.sin6.sin6_addr = info_ind->remote_ip[i].ipv6; + remote_sockaddr.u.sin6.sin6_port = info_ind->remote_port[i]; + break; + default: + continue; + } + + LOGP(DL1IF, LOGL_DEBUG, " NS%d nsvci=%d\n", i, info_ind->nsvci[i]); + LOGP(DL1IF, LOGL_DEBUG, " NS%d local_port=%d\n", i, info_ind->local_port[i]); + LOGP(DL1IF, LOGL_DEBUG, " NS%d remote_port=%d\n", i, info_ind->remote_port[i]); + + if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote_sockaddr.u.sas)) + strcpy(sockstr.ip, "invalid"); + + LOGP(DL1IF, LOGL_DEBUG, " NS%d remote_ip=%s\n", i, sockstr.ip); + 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:%d!\n", + sockstr.ip, sockstr.port); + continue; + } + + good_nsvc++; + } + + if (good_nsvc == 0) { + LOGP(DL1IF, LOGL_ERROR, "No NSVC available to connect to the SGSN!\n"); + goto bssgp_failed; + } + + + bts->cs1 = !!(info_ind->flags & PCU_IF_FLAG_CS1); bts->cs2 = !!(info_ind->flags & PCU_IF_FLAG_CS2); bts->cs3 = !!(info_ind->flags & PCU_IF_FLAG_CS3); @@ -654,7 +696,7 @@ bssgp_failed: pcu_tx_act_req(trx, ts, 1); pdch->enable(); } - pdch->tsc = info_ind->trx[trx].tsc[ts]; + pdch->tsc = info_ind->trx[trx].ts[ts].tsc; LOGP(DL1IF, LOGL_INFO, "PDCH: trx=%d ts=%d\n", trx, ts); } else { diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp index eb6d80df..8bad1d42 100644 --- a/tests/emu/pcu_emu.cpp +++ b/tests/emu/pcu_emu.cpp @@ -103,8 +103,10 @@ void create_and_connect_bssgp(struct gprs_rlcmac_bts *bts, 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 = gprs_bssgp_init(bts, 20, 20, 901, 99, false, 1, 0, 0); + gprs_nsvc_create_and_connect(bts, &local, &remote, + 20, 20); + pcu->on_unblock_ack = bvci_unblocked; pcu->on_dl_unit_data = bssgp_data; } |