Use the new NS2 lib

Depends: Id7edb8feb96436ba170383fc62d43ceb16955d53 (libosmocore)
Depends: I2a9dcd14f4ad16211c0f6d98812ad4a13e910c2a (libosmocore)
Change-Id: Ib389925cf5c9f18951af6242c31ea70476218e9a
This commit is contained in:
Alexander Couzens 2020-09-16 21:52:02 +02:00
parent 0a369e560c
commit 290d9030e9
9 changed files with 247 additions and 188 deletions

View File

@ -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 {

View File

@ -30,6 +30,7 @@
extern "C" {
#include <osmocom/gsm/protocol/gsm_23_003.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#include <osmocom/core/utils.h>
#include "coding_scheme.h"
}
@ -51,7 +52,6 @@ extern uint16_t spoof_mcc, spoof_mnc;
extern bool spoof_mnc_3_digits;
static void bvc_timeout(void *_priv);
static int gprs_ns_reconnect(struct gprs_nsvc *nsvc);
static int parse_ra_cap(struct tlv_parsed *tp, MS_Radio_Access_capability_t *rac)
{
@ -549,75 +549,91 @@ 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)
void gprs_ns_prim_status_cb(struct osmo_gprs_ns2_prim *nsp)
{
int rc = 0;
switch (event) {
case GPRS_NS_EVT_UNIT_DATA:
/* hand the message into the BSSGP implementation */
rc = gprs_bssgp_pcu_rcvmsg(msg);
switch (nsp->u.status.cause) {
case NS_AFF_CAUSE_SNS_CONFIGURED:
LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d SNS configured.\n", nsp->nsei);
break;
default:
LOGP(DPCU, LOGL_NOTICE, "RLCMAC: Unknown event %u from NS\n", event);
rc = -EIO;
break;
}
return rc;
}
static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
struct ns_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) {
LOGP(DPCU, LOGL_ERROR, "Signal received of unknown NSVC\n");
return -EINVAL;
}
switch (signal) {
case S_SNS_CONFIGURED:
the_pcu.bvc_sig_reset = 0;
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);
bvc_timeout(NULL);
break;
case S_NS_UNBLOCK:
case NS_AFF_CAUSE_RECOVERY:
LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became available\n", nsp->nsei);
if (!the_pcu.nsvc_unblocked) {
the_pcu.nsvc_unblocked = 1;
LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n",
the_pcu.nsvc->nsvci);
the_pcu.bvc_sig_reset = 0;
the_pcu.bvc_reset = 0;
the_pcu.bvc_unblocked = 0;
the_pcu.nsvc_unblocked = 1;
bvc_timeout(NULL);
}
break;
case S_NS_BLOCK:
case NS_AFF_CAUSE_FAILURE:
LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became unavailable\n", nsp->nsei);
if (the_pcu.nsvc_unblocked) {
the_pcu.nsvc_unblocked = 0;
osmo_timer_del(&the_pcu.bvc_timer);
the_pcu.bvc_sig_reset = 0;
the_pcu.bvc_reset = 0;
the_pcu.bvc_unblocked = 0;
LOGP(DPCU, LOGL_NOTICE, "NS-VC is blocked.\n");
}
break;
case S_NS_ALIVE_EXP:
LOGP(DPCU, LOGL_NOTICE, "Tns alive expired too often, "
"re-starting RESET procedure\n");
gprs_ns_reconnect(nssd->nsvc);
default:
LOGP(DPCU, LOGL_NOTICE,
"NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, nsp->oph.operation),
nsp->oph.primitive);
break;
}
}
/* called by the ns layer */
int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
struct osmo_gprs_ns2_prim *nsp;
int rc = 0;
if (oph->sap != SAP_NS)
return 0;
nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);
if (oph->operation != PRIM_OP_INDICATION) {
LOGP(DPCU, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, oph->operation),
oph->operation);
return 0;
}
switch (oph->primitive) {
case PRIM_NS_UNIT_DATA:
/* hand the message into the BSSGP implementation */
/* add required msg fields for Gb layer */
msgb_bssgph(oph->msg) = oph->msg->l3h;
msgb_bvci(oph->msg) = nsp->bvci;
msgb_nsei(oph->msg) = nsp->nsei;
rc = gprs_bssgp_pcu_rcvmsg(oph->msg);
break;
case PRIM_NS_STATUS:
gprs_ns_prim_status_cb(nsp);
break;
default:
LOGP(DPCU, LOGL_NOTICE,
"NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, oph->operation),
oph->primitive);
break;
}
return 0;
return rc;
}
/* called by the bssgp layer to send NS PDUs */
int gprs_gp_send_cb(void *ctx, struct msgb *msg)
{
struct gprs_ns2_inst *nsi = (struct gprs_ns2_inst *) ctx;
struct osmo_gprs_ns2_prim nsp = {};
nsp.nsei = msgb_nsei(msg);
nsp.bvci = msgb_bvci(msg);
osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,
PRIM_OP_REQUEST, msg);
return gprs_ns2_recv_prim(nsi, &nsp.oph);
}
static unsigned count_pdch(const struct gprs_rlcmac_bts *bts)
@ -904,77 +920,63 @@ static void bvc_timeout(void *_priv)
osmo_timer_schedule(&the_pcu.bvc_timer, the_pcu.bts->fc_interval, 0);
}
static int gprs_ns_reconnect(struct gprs_nsvc *nsvc)
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_nsvc *nsvc2;
struct gprs_ns2_vc *nsvc;
struct gprs_ns2_vc_bind *bind;
int rc;
if (nsvc != the_pcu.nsvc) {
LOGP(DBSSGP, LOGL_ERROR, "NSVC is invalid\n");
return -EBADF;
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 1;
}
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;
bts->nse = gprs_ns2_nse_by_nsei(bts->nsi, nsei);
if (!bts->nse)
bts->nse = gprs_ns2_create_nse(bts->nsi, nsei);
if (!bts->nse) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSE\n");
return 1;
}
return 0;
bts->nsei = nsei;
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)
LOGP(DBSSGP, LOGL_ERROR, "Failed to connect!\n");
return rc;
}
/* 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 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)
{
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 */
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);
if (rc < 0) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n");
gprs_ns_close(bssgp_nsi);
return NULL;
}
dest.sin_family = AF_INET;
dest.sin_port = htons(sgsn_port);
dest.sin_addr.s_addr = htonl(sgsn_ip);
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);
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;
return NULL;
}
the_pcu.bctx->ra_id.mcc = spoof_mcc ? : mcc;
@ -989,37 +991,27 @@ 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_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;
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;
bts->nse = NULL;
}
struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void)

View File

@ -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;
@ -76,16 +75,21 @@ struct gprs_bssgp_pcu {
struct tlv_parsed *tp);
};
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,
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_bssgp_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
struct msgb *msg, uint16_t bvci);
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);
void gprs_bssgp_destroy(void);
int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
int gprs_gp_send_cb(void *ctx, struct msgb *msg);
void gprs_bssgp_destroy(struct gprs_rlcmac_bts *bts);
struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void);

View File

@ -121,7 +121,7 @@ for the reset. */
gprs_rlcmac_tbf::free_all(&bts->trx[trx]);
}
gprs_bssgp_destroy();
gprs_bssgp_destroy(bts);
exit(0);
}

View File

@ -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,9 @@ 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;
struct in_addr ia;
struct osmo_sockaddr local_sockaddr = {}, remote_sockaddr = {};
int rc = 0;
int good_nsvc = 0;
unsigned int trx_nr, ts_nr;
int i;
@ -517,7 +519,7 @@ bssgp_failed:
for (ts_nr = 0; ts_nr < ARRAY_SIZE(bts->trx[0].pdch); ts_nr++)
bts->trx[trx_nr].pdch[ts_nr].free_resources();
}
gprs_bssgp_destroy();
gprs_bssgp_destroy(bts);
exit(0);
}
LOGP(DL1IF, LOGL_INFO, "BTS available\n");
@ -566,30 +568,65 @@ 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 = info_ind->remote_ip[0].v4.s_addr;
LOGP(DL1IF, LOGL_DEBUG, " remote_ip=%s\n", inet_ntoa(ia));
switch (info_ind->address_type[0]) {
case PCU_IF_ADDR_TYPE_IPV4:
break;
case PCU_IF_ADDR_TYPE_IPV6:
LOGP(DL1IF, LOGL_ERROR, "This PCU does not support IPv6 NSVC!\n");
goto bssgp_failed;
default:
LOGP(DL1IF, LOGL_ERROR, "No IPv4 NSVC given!\n");
pcu = gprs_bssgp_init(
bts,
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, "Failed to init BSSGP\n");
goto bssgp_failed;
}
pcu = gprs_bssgp_create_and_connect(bts, info_ind->local_port[0],
ntohl(info_ind->remote_ip[0].v4.s_addr), 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);
if (!pcu) {
LOGP(DL1IF, LOGL_NOTICE, "SGSN is not available\n");
for (int i=0; i<2; i++) {
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%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;
}

View File

@ -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,6 @@ int main(int argc, char *argv[])
osmo_stats_init(tall_pcu_ctx);
rate_ctr_init(tall_pcu_ctx);
gprs_ns_set_log_ss(DNS);
bssgp_set_log_ss(DBSSGP);
pcu_vty_info.tall_ctx = tall_pcu_ctx;
@ -289,12 +288,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(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
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(gprs_gp_send_cb, bts->nsi);
gprs_ns2_vty_init(bts->nsi, NULL);
rc = vty_read_config_file(config_file, NULL);
if (rc < 0 && config_given) {
@ -306,6 +306,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) {

View File

@ -13,6 +13,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/pcu/pcuif_proto.h>
#include <osmocom/gprs/gprs_ns2.h>
#include "pcu_vty.h"
#include "gprs_rlcmac.h"
#include <pdch.h>
@ -1096,10 +1097,13 @@ DEFUN(cfg_pcu_gb_dialect,
{
struct gprs_rlcmac_bts *bts = bts_main_data();
if (!strcmp(argv[0], "ip-sns"))
if (!strcmp(argv[0], "ip-sns")) {
bts->gb_dialect_sns = true;
else
gprs_ns2_vty_force_vc_mode(true, NS2_VC_MODE_ALIVE, "gb-dialect is ip-sns");
} else {
bts->gb_dialect_sns = false;
gprs_ns2_vty_force_vc_mode(false, 0, NULL);
}
return CMD_SUCCESS;
}

View File

@ -93,15 +93,28 @@ 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;
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_init(bts, 20, 20, 901, 99, false, 1, 0, 0);
gprs_nsvc_create_and_connect(bts, &local, &remote,
20, 20);
pcu = gprs_bssgp_create_and_connect(bts, 0, sgsn_ip, sgsn_port,
20, 20, 20, 901, 99, false, 1, 0, 0);
pcu->on_unblock_ack = bvci_unblocked;
pcu->on_dl_unit_data = bssgp_data;
}
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 +122,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(tall_pcu_ctx, &gprs_ns_prim_cb, NULL);
if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
abort();
}
@ -121,7 +134,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(gprs_gp_send_cb, bts->nsi);
create_and_connect_bssgp(bts, INADDR_LOOPBACK, 23000);
for (;;)
osmo_select_main(0);

View File

@ -470,15 +470,15 @@ static void test_tbf_exhaustion()
fprintf(stderr, "=== start %s ===\n", __func__);
bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
if (!bssgp_nsi) {
bts = the_bts.bts_data();
bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
abort();
}
bts = the_bts.bts_data();
setup_bts(&the_bts, ts_no);
gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
for (i = 0; i < 1024; i++) {
uint32_t tlli = 0xc0000000 + i;
@ -497,7 +497,7 @@ static void test_tbf_exhaustion()
OSMO_ASSERT(rc == -EBUSY);
fprintf(stderr, "=== end %s ===\n", __func__);
gprs_bssgp_destroy();
gprs_bssgp_destroy(bts);
}
static void test_tbf_dl_llc_loss()
@ -514,20 +514,20 @@ static void test_tbf_dl_llc_loss()
uint8_t buf[19];
bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
if (!bssgp_nsi) {
bts = the_bts.bts_data();
bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
abort();
}
fprintf(stderr, "=== start %s ===\n", __func__);
bts = the_bts.bts_data();
setup_bts(&the_bts, ts_no);
/* keep the MS object 10 seconds */
OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2030, 10, OSMO_TDEF_S) == 0);
gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 2234, 2234, 2234, 1, 1, false, 0, 0, 0);
gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
/* Handle LLC frame 1 */
memset(buf, 1, sizeof(buf));
@ -582,7 +582,7 @@ static void test_tbf_dl_llc_loss()
fprintf(stderr, "=== end %s ===\n", __func__);
gprs_bssgp_destroy();
gprs_bssgp_destroy(bts);
}
static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
@ -2165,19 +2165,19 @@ static void test_tbf_gprs_egprs()
fprintf(stderr, "=== start %s ===\n", __func__);
bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
if (!bssgp_nsi) {
bts = the_bts.bts_data();
bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
abort();
}
bts = the_bts.bts_data();
setup_bts(&the_bts, ts_no);
/* EGPRS-only */
bts->egprs_enabled = 1;
gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 3234, 3234, 3234, 1, 1, false, 0, 0, 0);
gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
/* Does not support EGPRS */
rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
@ -2186,12 +2186,13 @@ static void test_tbf_gprs_egprs()
OSMO_ASSERT(rc == -EBUSY);
fprintf(stderr, "=== end %s ===\n", __func__);
gprs_bssgp_destroy();
gprs_bssgp_destroy(bts);
}
static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
bool free, bool end)
{
gprs_rlcmac_bts *bts = dl_tbf->bts->bts_data();
if (!dl_tbf) {
fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
return;
@ -2213,7 +2214,7 @@ static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_
if (end) {
fprintf(stderr, "=== end %s ===\n", test);
gprs_bssgp_destroy();
gprs_bssgp_destroy(bts);
}
}
@ -2228,13 +2229,13 @@ static void test_tbf_ws()
fprintf(stderr, "=== start %s ===\n", __func__);
bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
if (!bssgp_nsi) {
bts = the_bts.bts_data();
bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
abort();
}
bts = the_bts.bts_data();
setup_bts(&the_bts, ts_no);
bts->ws_base = 128;
@ -2245,7 +2246,7 @@ static void test_tbf_ws()
bts->trx[0].pdch[4].enable();
bts->trx[0].pdch[5].enable();
gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 4234, 4234, 4234, 1, 1, false, 0, 0, 0);
gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
/* Does no support EGPRS */
ms = the_bts.ms_alloc(ms_class, 0);
@ -2274,13 +2275,13 @@ static void test_tbf_update_ws(void)
fprintf(stderr, "=== start %s ===\n", __func__);
bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
if (!bssgp_nsi) {
bts = the_bts.bts_data();
bts->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
if (!bts->nsi) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
abort();
}
bts = the_bts.bts_data();
setup_bts(&the_bts, ts_no);
bts->ws_base = 128;
@ -2291,7 +2292,7 @@ static void test_tbf_update_ws(void)
bts->trx[0].pdch[4].enable();
bts->trx[0].pdch[5].enable();
gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 5234, 5234, 5234, 1, 1, false, 0, 0, 0);
gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
/* EGPRS-only */
bts->egprs_enabled = 1;