Use the new NS2 lib
Depends: Id7edb8feb96436ba170383fc62d43ceb16955d53 (libosmocore) Depends: I2a9dcd14f4ad16211c0f6d98812ad4a13e910c2a (libosmocore) Change-Id: Ib389925cf5c9f18951af6242c31ea70476218e9a
This commit is contained in:
parent
0a369e560c
commit
290d9030e9
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ for the reset. */
|
|||
gprs_rlcmac_tbf::free_all(&bts->trx[trx]);
|
||||
}
|
||||
|
||||
gprs_bssgp_destroy();
|
||||
gprs_bssgp_destroy(bts);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue