summaryrefslogtreecommitdiffstats
path: root/openbsc/src/libbsc
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2011-08-17 22:44:07 +0200
committerHarald Welte <laforge@gnumonks.org>2011-08-19 22:38:35 +0200
commited5cacb240b846c106f0fc6a3ab8e8721f4c70a5 (patch)
treeba6bffbf0c95ecc0c50b5335bed77f3a2b29120f /openbsc/src/libbsc
parent7abecfcfc9ef94c1367cd88ac858b79d20f75db0 (diff)
src: port openBSC over libosmo-abis0.9.15
This is a big patch that ports openBSC over libosmo-abis. Sorry, the changes that are included here are all dependent of libosmo-abis, splitting them into smaller pieces would leave the repository in some intermediate state, which is not desired. The main changes are: - The directory libabis/ has been removed as it now lives in libosmo-abis. - new configuration file format for nanoBTS and HSL femto, we need to define the virtual e1_line and attach it to the OML link. - all the existing BTS drivers (nanoBTS, hsl femto, Nokia site, BS11 and rbs2000) now use the new libosmo-abis framework. - use r232 input driver available in libosmo-abis for bs11_config. - use ipa_msg_recv instead of old ipaccess_read_msg function. - delete definition of gsm_e1_subslot and input_signal_data. These structures now lives in libosmo-abis. Most of this patch are deletions of libabis/ which has been moved to libosmo-abis. This patch also modifies openBSC to use all the new definitions available in libosmocore and libosmo-abis. In order to do that, we have replaced the following: - DINP, DMI, DMIB and DMUX by their respective DL* correspondences. - SS_GLOBAL by SS_L_GLOBAL - SS_INPUT by SS_L_INPUT - S_GLOBAL_SHUTDOWN by S_L_GLOBAL_SHUTDOWN - SS_INPUT by SS_L_INPUT - S_INP_* by S_L_INP_* sub-signals - E1INP_NODE by L_E1INP_NODE vty node This patch has been tested with: - one nanoBTS - the HSL femto with the examples available under libosmo-abis - BS11 with both dahdi and misdn drivers.
Diffstat (limited to 'openbsc/src/libbsc')
-rw-r--r--openbsc/src/libbsc/abis_nm.c24
-rw-r--r--openbsc/src/libbsc/abis_om2000.c2
-rw-r--r--openbsc/src/libbsc/abis_rsl.c2
-rw-r--r--openbsc/src/libbsc/bsc_init.c21
-rw-r--r--openbsc/src/libbsc/bsc_msc.c4
-rw-r--r--openbsc/src/libbsc/bsc_vty.c33
-rw-r--r--openbsc/src/libbsc/bts_ericsson_rbs2000.c26
-rw-r--r--openbsc/src/libbsc/bts_hsl_femtocell.c155
-rw-r--r--openbsc/src/libbsc/bts_ipaccess_nanobts.c194
-rw-r--r--openbsc/src/libbsc/bts_nokia_site.c52
-rw-r--r--openbsc/src/libbsc/bts_siemens_bs11.c18
-rw-r--r--openbsc/src/libbsc/e1_config.c125
12 files changed, 525 insertions, 131 deletions
diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c
index a41414a98..027a2638b 100644
--- a/openbsc/src/libbsc/abis_nm.c
+++ b/openbsc/src/libbsc/abis_nm.c
@@ -43,7 +43,7 @@
#include <openbsc/abis_nm.h>
#include <openbsc/misdn.h>
#include <openbsc/signal.h>
-#include <openbsc/e1_input.h>
+#include <osmocom/abis/e1_input.h>
#define OM_ALLOC_SIZE 1024
#define OM_HEADROOM_SIZE 128
@@ -114,6 +114,26 @@ static struct msgb *nm_msgb_alloc(void)
"OML");
}
+int _abis_nm_sendmsg(struct msgb *msg, int to_trx_oml)
+{
+ struct e1inp_sign_link *sign_link = msg->dst;
+
+ msg->l2h = msg->data;
+
+ if (!msg->dst) {
+ LOGP(DNM, LOGL_ERROR, "%s: msg->dst == NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Check for TRX-specific OML link first */
+ if (to_trx_oml) {
+ if (!sign_link->trx->oml_link)
+ return -ENODEV;
+ msg->dst = sign_link->trx->oml_link;
+ }
+ return abis_sendmsg(msg);
+}
+
/* Send a OML NM Message from BSC to BTS */
static int abis_nm_queue_msg(struct gsm_bts *bts, struct msgb *msg)
{
@@ -480,7 +500,7 @@ static int abis_nm_rx_lmt_event(struct msgb *mb)
return 0;
}
-static void abis_nm_queue_send_next(struct gsm_bts *bts)
+void abis_nm_queue_send_next(struct gsm_bts *bts)
{
int wait = 0;
struct msgb *msg;
diff --git a/openbsc/src/libbsc/abis_om2000.c b/openbsc/src/libbsc/abis_om2000.c
index a4a3f23bf..22164627d 100644
--- a/openbsc/src/libbsc/abis_om2000.c
+++ b/openbsc/src/libbsc/abis_om2000.c
@@ -40,7 +40,7 @@
#include <openbsc/abis_nm.h>
#include <openbsc/abis_om2000.h>
#include <openbsc/signal.h>
-#include <openbsc/e1_input.h>
+#include <osmocom/abis/e1_input.h>
#define OM_ALLOC_SIZE 1024
#define OM_HEADROOM_SIZE 128
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index 86452686d..b4babc301 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -38,7 +38,7 @@
#include <openbsc/signal.h>
#include <openbsc/meas_rep.h>
#include <openbsc/rtp_proxy.h>
-#include <openbsc/e1_input.h>
+#include <osmocom/abis/e1_input.h>
#include <osmocom/gsm/rsl.h>
#include <osmocom/core/talloc.h>
diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c
index 1d885db37..84dfa6e80 100644
--- a/openbsc/src/libbsc/bsc_init.c
+++ b/openbsc/src/libbsc/bsc_init.c
@@ -82,7 +82,7 @@ int bsc_shutdown_net(struct gsm_network *net)
llist_for_each_entry(bts, &net->bts_list, list) {
LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
- osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_BTS_CLOSE_OM, bts);
+ osmo_signal_dispatch(SS_L_GLOBAL, S_GLOBAL_BTS_CLOSE_OM, bts);
}
return 0;
@@ -274,11 +274,11 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
struct gsm_bts_trx *trx = isd->trx;
int ts_no, lchan_no;
- if (subsys != SS_INPUT)
+ if (subsys != SS_L_INPUT)
return -EINVAL;
switch (signal) {
- case S_INP_TEI_UP:
+ case S_L_INP_TEI_UP:
if (isd->link_type == E1INP_SIGN_OML) {
/* TODO: this is required for the Nokia BTS, hopping is configured
during OML, other MA is not set. */
@@ -300,8 +300,8 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
if (isd->link_type == E1INP_SIGN_RSL)
bootstrap_rsl(trx);
break;
- case S_INP_TEI_DN:
- LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", isd->link_type, trx);
+ case S_L_INP_TEI_DN:
+ LOGP(DLMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", isd->link_type, trx);
if (isd->link_type == E1INP_SIGN_OML)
osmo_counter_inc(trx->bts->network->stats.bts.oml_fail);
@@ -469,7 +469,7 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *),
return rc;
osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
- osmo_signal_register_handler(SS_INPUT, inp_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
rc = bootstrap_bts(bts);
@@ -477,14 +477,7 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *),
LOGP(DNM, LOGL_FATAL, "Error bootstrapping BTS\n");
return rc;
}
- switch (bts->type) {
- case GSM_BTS_TYPE_NANOBTS:
- case GSM_BTS_TYPE_HSL_FEMTO:
- break;
- default:
- rc = e1_reconfig_bts(bts);
- break;
- }
+ rc = e1_reconfig_bts(bts);
if (rc < 0) {
LOGP(DNM, LOGL_FATAL, "Error enabling E1 input driver\n");
return rc;
diff --git a/openbsc/src/libbsc/bsc_msc.c b/openbsc/src/libbsc/bsc_msc.c
index e9ffce39a..66288a316 100644
--- a/openbsc/src/libbsc/bsc_msc.c
+++ b/openbsc/src/libbsc/bsc_msc.c
@@ -21,11 +21,13 @@
#include <openbsc/bsc_msc.h>
#include <openbsc/debug.h>
-#include <openbsc/ipaccess.h>
+#include <osmocom/abis/ipaccess.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/talloc.h>
+#include <osmocom/gsm/tlv.h>
+
#include <arpa/inet.h>
#include <sys/socket.h>
#include <errno.h>
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 8a5c7fdf2..a98779dac 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -30,7 +30,7 @@
#include <osmocom/core/linuxlist.h>
#include <openbsc/gsm_data.h>
-#include <openbsc/e1_input.h>
+#include <osmocom/abis/e1_input.h>
#include <openbsc/abis_nm.h>
#include <openbsc/abis_om2000.h>
#include <osmocom/core/utils.h>
@@ -506,10 +506,13 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
case GSM_BTS_TYPE_NANOBTS:
vty_out(vty, " ip.access unit_id %u %u%s",
bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
- vty_out(vty, " oml ip.access stream_id %u%s", bts->oml_tei, VTY_NEWLINE);
+ vty_out(vty, " oml ip.access stream_id %u line %u%s",
+ bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
break;
case GSM_BTS_TYPE_HSL_FEMTO:
vty_out(vty, " hsl serial-number %lu%s", bts->hsl.serno, VTY_NEWLINE);
+ vty_out(vty, " oml hsl line %u%s",
+ bts->oml_e1_link.e1_nr, VTY_NEWLINE);
break;
default:
config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
@@ -1507,12 +1510,12 @@ DEFUN(cfg_bts_serno,
DEFUN(cfg_bts_stream_id,
cfg_bts_stream_id_cmd,
- "oml ip.access stream_id <0-255>",
+ "oml ip.access stream_id <0-255> line E1_LINE",
OML_STR IPA_STR
"Set the ip.access Stream ID of the OML link of this BTS\n")
{
struct gsm_bts *bts = vty->index;
- int stream_id = atoi(argv[0]);
+ int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
if (!is_ipaccess_bts(bts)) {
vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
@@ -1520,6 +1523,27 @@ DEFUN(cfg_bts_stream_id,
}
bts->oml_tei = stream_id;
+ /* This is used by e1inp_bind_ops callback for each BTS model. */
+ bts->oml_e1_link.e1_nr = linenr;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_hsl_oml,
+ cfg_bts_hsl_oml_cmd,
+ "oml hsl line E1_LINE",
+ OML_STR "HSL femto Specific Options"
+ "Set OML link of this HSL femto BTS\n")
+{
+ struct gsm_bts *bts = vty->index;
+ int linenr = atoi(argv[0]);
+
+ if (!(bts->type == GSM_BTS_TYPE_HSL_FEMTO)) {
+ vty_out(vty, "%% BTS is not of HSL type%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bts->oml_e1_link.e1_nr = linenr;
return CMD_SUCCESS;
}
@@ -2624,6 +2648,7 @@ int bsc_vty_init(const struct log_info *cat)
install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
install_element(BTS_NODE, &cfg_bts_serno_cmd);
install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
+ install_element(BTS_NODE, &cfg_bts_hsl_oml_cmd);
install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
install_element(BTS_NODE, &cfg_bts_challoc_cmd);
diff --git a/openbsc/src/libbsc/bts_ericsson_rbs2000.c b/openbsc/src/libbsc/bts_ericsson_rbs2000.c
index 9c98a9fef..28e7df4cc 100644
--- a/openbsc/src/libbsc/bts_ericsson_rbs2000.c
+++ b/openbsc/src/libbsc/bts_ericsson_rbs2000.c
@@ -26,10 +26,10 @@
#include <openbsc/gsm_data.h>
#include <openbsc/abis_om2000.h>
#include <openbsc/abis_nm.h>
-#include <openbsc/e1_input.h>
+#include <osmocom/abis/e1_input.h>
#include <openbsc/signal.h>
-#include "../libabis/input/lapd.h"
+#include <osmocom/abis/lapd.h>
static void bootstrap_om_bts(struct gsm_bts *bts)
{
@@ -83,7 +83,7 @@ static int gbl_sig_cb(unsigned int subsys, unsigned int signal,
{
struct gsm_bts *bts;
- if (subsys != SS_GLOBAL)
+ if (subsys != SS_L_GLOBAL)
return 0;
switch (signal) {
@@ -103,11 +103,11 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
{
struct input_signal_data *isd = signal_data;
- if (subsys != SS_INPUT)
+ if (subsys != SS_L_INPUT)
return 0;
switch (signal) {
- case S_INP_TEI_UP:
+ case S_L_INP_TEI_UP:
switch (isd->link_type) {
case E1INP_SIGN_OML:
if (isd->trx->bts->type != GSM_BTS_TYPE_RBS2000)
@@ -119,18 +119,18 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
break;
}
break;
- case S_INP_LINE_INIT:
+ case S_L_INP_LINE_INIT:
/* Right now Ericsson RBS are only supported on DAHDI */
if (strcasecmp(isd->line->driver->name, "DAHDI"))
break;
start_sabm_in_line(isd->line, 1);
break;
- case S_INP_LINE_ALARM:
+ case S_L_INP_LINE_ALARM:
if (strcasecmp(isd->line->driver->name, "DAHDI"))
break;
start_sabm_in_line(isd->line, 0);
break;
- case S_INP_LINE_NOALARM:
+ case S_L_INP_LINE_NOALARM:
if (strcasecmp(isd->line->driver->name, "DAHDI"))
break;
start_sabm_in_line(isd->line, 1);
@@ -244,12 +244,18 @@ static void config_write_bts(struct vty *vty, struct gsm_bts *bts)
static int bts_model_rbs2k_start(struct gsm_network *net);
+static void bts_model_rbs2k_e1line_bind_ops(struct e1inp_line *line)
+{
+ e1inp_line_bind_ops(line, &bts_isdn_e1inp_line_ops);
+}
+
static struct gsm_bts_model model_rbs2k = {
.type = GSM_BTS_TYPE_RBS2000,
.name = "rbs2000",
.start = bts_model_rbs2k_start,
.oml_rcvmsg = &abis_om2k_rcvmsg,
.config_write_bts = &config_write_bts,
+ .e1line_bind_ops = &bts_model_rbs2k_e1line_bind_ops,
};
static int bts_model_rbs2k_start(struct gsm_network *net)
@@ -260,8 +266,8 @@ static int bts_model_rbs2k_start(struct gsm_network *net)
gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_HOPPING);
gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_HSCSD);
- osmo_signal_register_handler(SS_INPUT, inp_sig_cb, NULL);
- osmo_signal_register_handler(SS_GLOBAL, gbl_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_GLOBAL, gbl_sig_cb, NULL);
osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
return 0;
diff --git a/openbsc/src/libbsc/bts_hsl_femtocell.c b/openbsc/src/libbsc/bts_hsl_femtocell.c
index 8463202a3..ebab34aeb 100644
--- a/openbsc/src/libbsc/bts_hsl_femtocell.c
+++ b/openbsc/src/libbsc/bts_hsl_femtocell.c
@@ -28,13 +28,18 @@
#include <openbsc/abis_nm.h>
#include <openbsc/abis_rsl.h>
#include <openbsc/signal.h>
-#include <openbsc/e1_input.h>
+#include <openbsc/debug.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/abis/e1_input.h>
+#include <osmocom/abis/ipaccess.h>
static int bts_model_hslfemto_start(struct gsm_network *net);
+static void bts_model_hslfemto_e1line_bind_ops(struct e1inp_line *line);
static struct gsm_bts_model model_hslfemto = {
.type = GSM_BTS_TYPE_HSL_FEMTO,
.start = bts_model_hslfemto_start,
+ .e1line_bind_ops = &bts_model_hslfemto_e1line_bind_ops,
.nm_att_tlvdef = {
.def = {
/* no HSL specific OML attributes that we know of */
@@ -121,7 +126,7 @@ static int hslfemto_bootstrap_om(struct gsm_bts *bts)
cur = msgb_put(msg, sizeof(oml_arfcn_bsic));
memcpy(msg->data, oml_arfcn_bsic, sizeof(oml_arfcn_bsic));
msg->dst = bts->c0->rsl_link;
- _abis_nm_sendmsg(msg, 0);
+ abis_sendmsg(msg);
/* Delay the OPSTART until after SI have been set via RSL */
//abis_nm_opstart(bts, NM_OC_BTS, 255, 255, 255);
@@ -135,11 +140,11 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
{
struct input_signal_data *isd = signal_data;
- if (subsys != SS_INPUT)
+ if (subsys != SS_L_INPUT)
return 0;
switch (signal) {
- case S_INP_TEI_UP:
+ case S_L_INP_TEI_UP:
switch (isd->link_type) {
case E1INP_SIGN_OML:
if (isd->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO)
@@ -151,6 +156,8 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
return 0;
}
+static struct gsm_network *hsl_gsmnet;
+
static int bts_model_hslfemto_start(struct gsm_network *net)
{
model_hslfemto.features.data = &model_hslfemto._features_data[0];
@@ -159,13 +166,147 @@ static int bts_model_hslfemto_start(struct gsm_network *net)
gsm_btsmodel_set_feature(&model_hslfemto, BTS_FEAT_GPRS);
gsm_btsmodel_set_feature(&model_hslfemto, BTS_FEAT_EGPRS);
- osmo_signal_register_handler(SS_INPUT, inp_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
- /* Call A-bis input driver, start socket for OML and RSL. */
- return hsl_setup(net);
+ hsl_gsmnet = net;
+ return 0;
}
int bts_model_hslfemto_init(void)
{
return gsm_bts_model_register(&model_hslfemto);
}
+
+#define OML_UP 0x0001
+#define RSL_UP 0x0002
+
+struct gsm_bts *find_bts_by_serno(struct gsm_network *net, uint64_t serno)
+{
+ struct gsm_bts *bts;
+
+ llist_for_each_entry(bts, &net->bts_list, list) {
+ if (bts->type != GSM_BTS_TYPE_HSL_FEMTO)
+ continue;
+
+ if (serno == bts->hsl.serno)
+ return bts;
+ }
+ return NULL;
+}
+
+/* This function is called once the OML/RSL link becomes up. */
+static struct e1inp_sign_link *
+hsl_sign_link_up(void *unit_data, struct e1inp_line *line,
+ enum e1inp_sign_type type)
+{
+ struct hsl_unit *dev = unit_data;
+ struct gsm_bts *bts;
+
+ bts = find_bts_by_serno(hsl_gsmnet, dev->serno);
+ if (!bts) {
+ LOGP(DLINP, LOGL_ERROR, "Unable to find BTS config for "
+ "serial number %lx\n", dev->serno);
+ return NULL;
+ }
+ DEBUGP(DLINP, "Identified HSL BTS Serial Number %lx\n", dev->serno);
+
+ /* we shouldn't hardcode it, but HSL femto also hardcodes it... */
+ bts->oml_tei = 255;
+ bts->c0->rsl_tei = 0;
+ bts->oml_link = e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML-1],
+ E1INP_SIGN_OML, bts->c0,
+ bts->oml_tei, 0);
+ bts->c0->rsl_link = e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML-1],
+ E1INP_SIGN_RSL, bts->c0,
+ bts->c0->rsl_tei, 0);
+ e1inp_event(&line->ts[E1INP_SIGN_OML-1], S_L_INP_TEI_UP, 255, 0);
+ e1inp_event(&line->ts[E1INP_SIGN_OML-1], S_L_INP_TEI_UP, 0, 0);
+ bts->ip_access.flags |= OML_UP;
+ bts->ip_access.flags |= (RSL_UP << 0);
+
+ return bts->oml_link;
+}
+
+void hsl_drop_oml(struct gsm_bts *bts)
+{
+ struct e1inp_line *line;
+
+ if (!bts->oml_link)
+ return;
+
+ line = bts->oml_link->ts->line;
+ e1inp_sign_link_destroy(bts->oml_link);
+ bts->oml_link = NULL;
+
+ e1inp_sign_link_destroy(bts->c0->rsl_link);
+ bts->c0->rsl_link = NULL;
+
+ bts->ip_access.flags = 0;
+}
+
+static void hsl_sign_link_down(struct e1inp_line *line)
+{
+ /* No matter what link went down, we close both signal links. */
+ struct e1inp_ts *ts = &line->ts[E1INP_SIGN_OML-1];
+ struct e1inp_sign_link *link;
+
+ llist_for_each_entry(link, &ts->sign.sign_links, list) {
+ struct gsm_bts *bts = link->trx->bts;
+
+ hsl_drop_oml(bts);
+ /* Yes, we only use the first element of the list. */
+ break;
+ }
+}
+
+/* This function is called if we receive one OML/RSL message. */
+static int hsl_sign_link(struct msgb *msg)
+{
+ int ret = 0;
+ struct e1inp_sign_link *link = msg->dst;
+ struct e1inp_ts *e1i_ts = link->ts;
+
+ switch (link->type) {
+ case E1INP_SIGN_OML:
+ if (!(link->trx->bts->ip_access.flags & OML_UP)) {
+ e1inp_event(e1i_ts, S_L_INP_TEI_UP,
+ link->tei, link->sapi);
+ link->trx->bts->ip_access.flags |= OML_UP;
+ }
+ ret = abis_nm_rcvmsg(msg);
+ break;
+ case E1INP_SIGN_RSL:
+ if (!(link->trx->bts->ip_access.flags &
+ (RSL_UP << link->trx->nr))) {
+ e1inp_event(e1i_ts, S_L_INP_TEI_UP,
+ link->tei, link->sapi);
+ link->trx->bts->ip_access.flags |=
+ (RSL_UP << link->trx->nr);
+ }
+ ret = abis_rsl_rcvmsg(msg);
+ break;
+ default:
+ LOGP(DLINP, LOGL_ERROR, "Unknown signal link type %d\n",
+ link->type);
+ msgb_free(msg);
+ break;
+ }
+ return ret;
+}
+
+static struct e1inp_line_ops hsl_e1inp_line_ops = {
+ .cfg = {
+ .ipa = {
+ .addr = "0.0.0.0",
+ .role = E1INP_LINE_R_BSC,
+ },
+ },
+ .sign_link_up = hsl_sign_link_up,
+ .sign_link_down = hsl_sign_link_down,
+ .sign_link = hsl_sign_link,
+};
+
+static void bts_model_hslfemto_e1line_bind_ops(struct e1inp_line *line)
+{
+ e1inp_line_bind_ops(line, &hsl_e1inp_line_ops);
+}
diff --git a/openbsc/src/libbsc/bts_ipaccess_nanobts.c b/openbsc/src/libbsc/bts_ipaccess_nanobts.c
index c86b1e1b0..42ac6b4a5 100644
--- a/openbsc/src/libbsc/bts_ipaccess_nanobts.c
+++ b/openbsc/src/libbsc/bts_ipaccess_nanobts.c
@@ -26,15 +26,27 @@
#include <openbsc/gsm_data.h>
#include <openbsc/signal.h>
#include <openbsc/abis_nm.h>
-#include <openbsc/e1_input.h> /* for ipaccess_setup() */
+#include <osmocom/abis/e1_input.h>
+#include <osmocom/gsm/tlv.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/talloc.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/abis_nm.h>
+#include <openbsc/abis_rsl.h>
+#include <openbsc/debug.h>
+#include <osmocom/abis/subchan_demux.h>
+#include <osmocom/abis/ipaccess.h>
+#include <osmocom/core/logging.h>
static int bts_model_nanobts_start(struct gsm_network *net);
+static void bts_model_nanobts_e1line_bind_ops(struct e1inp_line *line);
static struct gsm_bts_model model_nanobts = {
.type = GSM_BTS_TYPE_NANOBTS,
.name = "nanobts",
.start = bts_model_nanobts_start,
.oml_rcvmsg = &abis_nm_rcvmsg,
+ .e1line_bind_ops = bts_model_nanobts_e1line_bind_ops,
.nm_att_tlvdef = {
.def = {
/* ip.access specifics */
@@ -440,6 +452,8 @@ static int nm_sig_cb(unsigned int subsys, unsigned int signal,
return 0;
}
+static struct gsm_network *ipaccess_gsmnet;
+
static int bts_model_nanobts_start(struct gsm_network *net)
{
model_nanobts.features.data = &model_nanobts._features_data[0];
@@ -450,11 +464,185 @@ static int bts_model_nanobts_start(struct gsm_network *net)
osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
- /* Call A-bis input driver, start server sockets for OML and RSL. */
- return ipaccess_setup(net);
+ ipaccess_gsmnet = net;
+ return 0;
}
int bts_model_nanobts_init(void)
{
return gsm_bts_model_register(&model_nanobts);
}
+
+#define OML_UP 0x0001
+#define RSL_UP 0x0002
+
+static struct gsm_bts *
+find_bts_by_unitid(struct gsm_network *net, uint16_t site_id, uint16_t bts_id)
+{
+ struct gsm_bts *bts;
+
+ llist_for_each_entry(bts, &net->bts_list, list) {
+ if (!is_ipaccess_bts(bts))
+ continue;
+
+ if (bts->ip_access.site_id == site_id &&
+ bts->ip_access.bts_id == bts_id)
+ return bts;
+ }
+ return NULL;
+}
+
+/* These are exported because they are used by the VTY interface. */
+void ipaccess_drop_rsl(struct gsm_bts_trx *trx)
+{
+ if (!trx->rsl_link)
+ return;
+
+ e1inp_sign_link_destroy(trx->rsl_link);
+ trx->rsl_link = NULL;
+}
+
+void ipaccess_drop_oml(struct gsm_bts *bts)
+{
+ struct gsm_bts_trx *trx;
+ struct e1inp_line *line;
+
+ if (!bts->oml_link)
+ return;
+
+ line = bts->oml_link->ts->line;
+
+ e1inp_sign_link_destroy(bts->oml_link);
+ bts->oml_link = NULL;
+
+ /* we have issues reconnecting RSL, drop everything. */
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ ipaccess_drop_rsl(trx);
+
+ bts->ip_access.flags = 0;
+}
+
+/* This function is called once the OML/RSL link becomes up. */
+static struct e1inp_sign_link *
+ipaccess_sign_link_up(void *unit_data, struct e1inp_line *line,
+ enum e1inp_sign_type type)
+{
+ struct gsm_bts *bts;
+ struct ipaccess_unit *dev = unit_data;
+ struct e1inp_sign_link *sign_link = NULL;
+
+ bts = find_bts_by_unitid(ipaccess_gsmnet, dev->site_id, dev->bts_id);
+ if (!bts) {
+ LOGP(DLINP, LOGL_ERROR, "Unable to find BTS configuration for "
+ " %u/%u/%u, disconnecting\n", dev->site_id,
+ dev->bts_id, dev->trx_id);
+ return NULL;
+ }
+ DEBUGP(DLINP, "Identified BTS %u/%u/%u\n",
+ dev->site_id, dev->bts_id, dev->trx_id);
+
+ switch(type) {
+ case E1INP_SIGN_OML:
+ /* remove old OML signal link for this BTS. */
+ ipaccess_drop_oml(bts);
+
+ /* create new OML link. */
+ sign_link = bts->oml_link =
+ e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML - 1],
+ E1INP_SIGN_OML, bts->c0,
+ bts->oml_tei, 0);
+ break;
+ case E1INP_SIGN_RSL: {
+ struct e1inp_ts *ts;
+ struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, dev->trx_id);
+
+ /* no OML link set yet? give up. */
+ if (!bts->oml_link)
+ return NULL;
+
+ /* remove old RSL link for this TRX. */
+ ipaccess_drop_rsl(trx);
+
+ /* set new RSL link for this TRX. */
+ line = bts->oml_link->ts->line;
+ ts = &line->ts[E1INP_SIGN_RSL + dev->trx_id - 1];
+ e1inp_ts_config_sign(ts, line);
+ sign_link = trx->rsl_link =
+ e1inp_sign_link_create(ts, E1INP_SIGN_RSL,
+ trx, trx->rsl_tei, 0);
+ trx->rsl_link->ts->sign.delay = 0;
+ break;
+ }
+ default:
+ break;
+ }
+ return sign_link;
+}
+
+static void ipaccess_sign_link_down(struct e1inp_line *line)
+{
+ /* No matter what link went down, we close both signal links. */
+ struct e1inp_ts *ts = &line->ts[E1INP_SIGN_OML-1];
+ struct e1inp_sign_link *link;
+
+ llist_for_each_entry(link, &ts->sign.sign_links, list) {
+ struct gsm_bts *bts = link->trx->bts;
+
+ ipaccess_drop_oml(bts);
+ /* Yes, we only use the first element of the list. */
+ break;
+ }
+}
+
+/* This function is called if we receive one OML/RSL message. */
+static int ipaccess_sign_link(struct msgb *msg)
+{
+ int ret = 0;
+ struct e1inp_sign_link *link = msg->dst;
+ struct e1inp_ts *e1i_ts = link->ts;
+
+ switch (link->type) {
+ case E1INP_SIGN_RSL:
+ if (!(link->trx->bts->ip_access.flags &
+ (RSL_UP << link->trx->nr))) {
+ e1inp_event(e1i_ts, S_L_INP_TEI_UP,
+ link->tei, link->sapi);
+ link->trx->bts->ip_access.flags |=
+ (RSL_UP << link->trx->nr);
+ }
+ ret = abis_rsl_rcvmsg(msg);
+ break;
+ case E1INP_SIGN_OML:
+ if (!(link->trx->bts->ip_access.flags & OML_UP)) {
+ e1inp_event(e1i_ts, S_L_INP_TEI_UP,
+ link->tei, link->sapi);
+ link->trx->bts->ip_access.flags |= OML_UP;
+ }
+ ret = abis_nm_rcvmsg(msg);
+ break;
+ default:
+ LOGP(DLINP, LOGL_ERROR, "Unknown signal link type %d\n",
+ link->type);
+ msgb_free(msg);
+ break;
+ }
+ return ret;
+}
+
+/* not static, ipaccess-config needs it. */
+struct e1inp_line_ops ipaccess_e1inp_line_ops = {
+ .cfg = {
+ .ipa = {
+ .addr = "0.0.0.0",
+ .role = E1INP_LINE_R_BSC,
+ },
+ },
+ .sign_link_up = ipaccess_sign_link_up,
+ .sign_link_down = ipaccess_sign_link_down,
+ .sign_link = ipaccess_sign_link,
+};
+
+static void bts_model_nanobts_e1line_bind_ops(struct e1inp_line *line)
+{
+ e1inp_line_bind_ops(line, &ipaccess_e1inp_line_ops);
+}
diff --git a/openbsc/src/libbsc/bts_nokia_site.c b/openbsc/src/libbsc/bts_nokia_site.c
index 8ba01d057..fa8f43eb3 100644
--- a/openbsc/src/libbsc/bts_nokia_site.c
+++ b/openbsc/src/libbsc/bts_nokia_site.c
@@ -33,12 +33,12 @@
#include <openbsc/debug.h>
#include <openbsc/gsm_data.h>
#include <openbsc/abis_nm.h>
-#include <openbsc/e1_input.h>
+#include <osmocom/abis/e1_input.h>
#include <openbsc/signal.h>
#include <osmocom/core/timer.h>
-#include "../libabis/input/lapd.h"
+#include <osmocom/abis/lapd.h>
/* TODO: put in a separate file ? */
@@ -48,7 +48,7 @@ extern int abis_nm_sendmsg(struct gsm_bts *bts, struct msgb *msg);
/* was static in system_information.c */
extern int generate_cell_chan_list(uint8_t * chan_list, struct gsm_bts *bts);
-static void abis_nm_queue_send_next(struct gsm_bts *bts);
+static void nokia_abis_nm_queue_send_next(struct gsm_bts *bts);
static void reset_timer_cb(void *_bts);
static int abis_nm_reset(struct gsm_bts *bts, uint16_t ref);
static int dump_elements(uint8_t * data, int len);
@@ -120,7 +120,7 @@ static int gbl_sig_cb(unsigned int subsys, unsigned int signal,
{
struct gsm_bts *bts;
- if (subsys != SS_GLOBAL)
+ if (subsys != SS_L_GLOBAL)
return 0;
switch (signal) {
@@ -140,16 +140,16 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
{
struct input_signal_data *isd = signal_data;
- if (subsys != SS_INPUT)
+ if (subsys != SS_L_INPUT)
return 0;
switch (signal) {
- case S_INP_LINE_INIT:
+ case S_L_INP_LINE_INIT:
start_sabm_in_line(isd->line, 1, SAPI_OML); /* start only OML */
break;
- case S_INP_TEI_DN:
+ case S_L_INP_TEI_DN:
break;
- case S_INP_TEI_UP:
+ case S_L_INP_TEI_UP:
switch (isd->link_type) {
case E1INP_SIGN_OML:
if (isd->trx->bts->type != GSM_BTS_TYPE_NOKIA_SITE)
@@ -162,7 +162,7 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
break;
}
break;
- case S_INP_TEI_UNKNOWN:
+ case S_L_INP_TEI_UNKNOWN:
/* We are receiving LAPD frames with one TEI that we do not
* seem to know, likely that we (the BSC) stopped working
* and lost our local states. However, the BTS is already
@@ -1235,7 +1235,7 @@ static int abis_nm_send_multi_segments(struct gsm_bts *bts, uint8_t msg_type,
if (ret < 0)
return ret;
- abis_nm_queue_send_next(bts);
+ nokia_abis_nm_queue_send_next(bts);
/* next segment */
len_remain -= len_to_send;
@@ -1415,7 +1415,7 @@ static int dump_elements(uint8_t * data, int len)
/* taken from abis_nm.c */
-static void abis_nm_queue_send_next(struct gsm_bts *bts)
+static void nokia_abis_nm_queue_send_next(struct gsm_bts *bts)
{
int wait = 0;
struct msgb *msg;
@@ -1423,7 +1423,7 @@ static void abis_nm_queue_send_next(struct gsm_bts *bts)
while (!llist_empty(&bts->abis_queue)) {
msg = msgb_dequeue(&bts->abis_queue);
wait = OBSC_NM_W_ACK_CB(msg);
- _abis_nm_sendmsg(msg, 0);
+ abis_sendmsg(msg);
if (wait)
break;
@@ -1445,9 +1445,9 @@ static void reset_timer_cb(void *_bts)
bts->nokia.wait_reset = 0;
/* OML link */
- line = e1inp_line_get(e1_link->e1_nr);
+ line = e1inp_line_find(e1_link->e1_nr);
if (!line) {
- LOGP(DINP, LOGL_ERROR, "BTS %u OML link referring to "
+ LOGP(DLINP, LOGL_ERROR, "BTS %u OML link referring to "
"non-existing E1 line %u\n", bts->nr, e1_link->e1_nr);
return;
}
@@ -1522,7 +1522,7 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
case NOKIA_MSG_CONF_REQ:
/* send ACK */
abis_nm_ack(bts, ref);
- abis_nm_queue_send_next(bts);
+ nokia_abis_nm_queue_send_next(bts);
/* send CONF_DATA */
abis_nm_send_config(bts, bts->nokia.bts_type);
bts->nokia.configured = 1;
@@ -1564,9 +1564,9 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
struct gsm_e1_subslot *e1_link = &bts->oml_e1_link;
struct e1inp_line *line;
/* OML link */
- line = e1inp_line_get(e1_link->e1_nr);
+ line = e1inp_line_find(e1_link->e1_nr);
if (!line) {
- LOGP(DINP, LOGL_ERROR,
+ LOGP(DLINP, LOGL_ERROR,
"BTS %u OML link referring to "
"non-existing E1 line %u\n", bts->nr,
e1_link->e1_nr);
@@ -1587,9 +1587,9 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
bts->nokia.configured = 0;
/* RSL Link */
- line = e1inp_line_get(e1_link->e1_nr);
+ line = e1inp_line_find(e1_link->e1_nr);
if (!line) {
- LOGP(DINP, LOGL_ERROR,
+ LOGP(DLINP, LOGL_ERROR,
"TRX (%u/%u) RSL link referring "
"to non-existing E1 line %u\n",
sign_link->trx->bts->nr, sign_link->trx->nr,
@@ -1643,7 +1643,7 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
break;
}
- abis_nm_queue_send_next(bts);
+ nokia_abis_nm_queue_send_next(bts);
return ret;
}
@@ -1696,11 +1696,17 @@ int abis_nokia_rcvmsg(struct msgb *msg)
static int bts_model_nokia_site_start(struct gsm_network *net);
+static void bts_model_nokia_site_e1line_bind_ops(struct e1inp_line *line)
+{
+ e1inp_line_bind_ops(line, &bts_isdn_e1inp_line_ops);
+}
+
static struct gsm_bts_model model_nokia_site = {
.type = GSM_BTS_TYPE_NOKIA_SITE,
.name = "nokia_site",
.start = bts_model_nokia_site_start,
- .oml_rcvmsg = &abis_nokia_rcvmsg
+ .oml_rcvmsg = &abis_nokia_rcvmsg,
+ .e1line_bind_ops = &bts_model_nokia_site_e1line_bind_ops,
};
static struct gsm_network *my_net;
@@ -1714,8 +1720,8 @@ static int bts_model_nokia_site_start(struct gsm_network *net)
gsm_btsmodel_set_feature(&model_nokia_site, BTS_FEAT_HOPPING);
gsm_btsmodel_set_feature(&model_nokia_site, BTS_FEAT_HSCSD);
- osmo_signal_register_handler(SS_INPUT, inp_sig_cb, NULL);
- osmo_signal_register_handler(SS_GLOBAL, gbl_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_GLOBAL, gbl_sig_cb, NULL);
osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
my_net = net;
diff --git a/openbsc/src/libbsc/bts_siemens_bs11.c b/openbsc/src/libbsc/bts_siemens_bs11.c
index df4a1dc23..2514d9977 100644
--- a/openbsc/src/libbsc/bts_siemens_bs11.c
+++ b/openbsc/src/libbsc/bts_siemens_bs11.c
@@ -25,16 +25,22 @@
#include <openbsc/debug.h>
#include <openbsc/gsm_data.h>
#include <openbsc/abis_nm.h>
-#include <openbsc/e1_input.h>
+#include <osmocom/abis/e1_input.h>
#include <openbsc/signal.h>
static int bts_model_bs11_start(struct gsm_network *net);
+static void bts_model_bs11_e1line_bind_ops(struct e1inp_line *line)
+{
+ e1inp_line_bind_ops(line, &bts_isdn_e1inp_line_ops);
+}
+
static struct gsm_bts_model model_bs11 = {
.type = GSM_BTS_TYPE_BS11,
.name = "bs11",
.start = bts_model_bs11_start,
.oml_rcvmsg = &abis_nm_rcvmsg,
+ .e1line_bind_ops = bts_model_bs11_e1line_bind_ops,
.nm_att_tlvdef = {
.def = {
[NM_ATT_AVAIL_STATUS] = { TLV_TYPE_TLV },
@@ -542,7 +548,7 @@ static int gbl_sig_cb(unsigned int subsys, unsigned int signal,
{
struct gsm_bts *bts;
- if (subsys != SS_GLOBAL)
+ if (subsys != SS_L_GLOBAL)
return 0;
switch (signal) {
@@ -562,11 +568,11 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
{
struct input_signal_data *isd = signal_data;
- if (subsys != SS_INPUT)
+ if (subsys != SS_L_INPUT)
return 0;
switch (signal) {
- case S_INP_TEI_UP:
+ case S_L_INP_TEI_UP:
switch (isd->link_type) {
case E1INP_SIGN_OML:
if (isd->trx->bts->type == GSM_BTS_TYPE_BS11)
@@ -586,8 +592,8 @@ static int bts_model_bs11_start(struct gsm_network *net)
gsm_btsmodel_set_feature(&model_bs11, BTS_FEAT_HOPPING);
gsm_btsmodel_set_feature(&model_bs11, BTS_FEAT_HSCSD);
- osmo_signal_register_handler(SS_INPUT, inp_sig_cb, NULL);
- osmo_signal_register_handler(SS_GLOBAL, gbl_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
+ osmo_signal_register_handler(SS_L_GLOBAL, gbl_sig_cb, NULL);
return 0;
}
diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c
index bd6ebba9d..cda131845 100644
--- a/openbsc/src/libbsc/e1_config.c
+++ b/openbsc/src/libbsc/e1_config.c
@@ -24,13 +24,14 @@
#include <netinet/in.h>
#include <openbsc/gsm_data.h>
-#include <openbsc/e1_input.h>
-#include <openbsc/trau_frame.h>
+#include <osmocom/abis/e1_input.h>
+#include <osmocom/abis/trau_frame.h>
#include <openbsc/trau_mux.h>
#include <openbsc/misdn.h>
-#include <openbsc/ipaccess.h>
+#include <osmocom/abis/ipaccess.h>
#include <osmocom/core/talloc.h>
#include <openbsc/debug.h>
+#include <openbsc/abis_rsl.h>
#define SAPI_L2ML 0
#define SAPI_OML 62
@@ -46,17 +47,17 @@ int e1_reconfig_ts(struct gsm_bts_trx_ts *ts)
struct e1inp_line *line;
struct e1inp_ts *e1_ts;
- DEBUGP(DMI, "e1_reconfig_ts(%u,%u,%u)\n", ts->trx->bts->nr, ts->trx->nr, ts->nr);
+ DEBUGP(DLMI, "e1_reconfig_ts(%u,%u,%u)\n", ts->trx->bts->nr, ts->trx->nr, ts->nr);
if (!e1_link->e1_ts) {
- LOGP(DINP, LOGL_ERROR, "TS (%u/%u/%u) without E1 timeslot?\n",
+ LOGP(DLINP, LOGL_ERROR, "TS (%u/%u/%u) without E1 timeslot?\n",
ts->nr, ts->trx->nr, ts->trx->bts->nr);
return 0;
}
- line = e1inp_line_get(e1_link->e1_nr);
+ line = e1inp_line_find(e1_link->e1_nr);
if (!line) {
- LOGP(DINP, LOGL_ERROR, "TS (%u/%u/%u) referring to "
+ LOGP(DLINP, LOGL_ERROR, "TS (%u/%u/%u) referring to "
"non-existing E1 line %u\n", ts->nr, ts->trx->nr,
ts->trx->bts->nr, e1_link->e1_nr);
return -ENOMEM;
@@ -66,7 +67,7 @@ int e1_reconfig_ts(struct gsm_bts_trx_ts *ts)
case GSM_PCHAN_TCH_F:
case GSM_PCHAN_TCH_H:
e1_ts = &line->ts[e1_link->e1_ts-1];
- e1inp_ts_config(e1_ts, line, E1INP_TS_TYPE_TRAU);
+ e1inp_ts_config_trau(e1_ts, line, subch_cb);
subch_demux_activate(&e1_ts->trau.demux, e1_link->e1_ts_ss);
break;
default:
@@ -85,28 +86,28 @@ int e1_reconfig_trx(struct gsm_bts_trx *trx)
int i;
if (!e1_link->e1_ts) {
- LOGP(DINP, LOGL_ERROR, "TRX (%u/%u) RSL link without "
+ LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) RSL link without "
"timeslot?\n", trx->bts->nr, trx->nr);
return -EINVAL;
}
/* RSL Link */
- line = e1inp_line_get(e1_link->e1_nr);
+ line = e1inp_line_find(e1_link->e1_nr);
if (!line) {
- LOGP(DINP, LOGL_ERROR, "TRX (%u/%u) RSL link referring "
+ LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) RSL link referring "
"to non-existing E1 line %u\n", trx->bts->nr,
trx->nr, e1_link->e1_nr);
return -ENOMEM;
}
sign_ts = &line->ts[e1_link->e1_ts-1];
- e1inp_ts_config(sign_ts, line, E1INP_TS_TYPE_SIGN);
+ e1inp_ts_config_sign(sign_ts, line);
/* Ericsson RBS have a per-TRX OML link in parallel to RSL */
if (trx->bts->type == GSM_BTS_TYPE_RBS2000) {
struct e1inp_sign_link *oml_link;
oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML, trx,
trx->rsl_tei, SAPI_OML);
if (!oml_link) {
- LOGP(DINP, LOGL_ERROR, "TRX (%u/%u) OML link creation "
+ LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) OML link creation "
"failed\n", trx->bts->nr, trx->nr);
return -ENOMEM;
}
@@ -117,7 +118,7 @@ int e1_reconfig_trx(struct gsm_bts_trx *trx)
rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
trx, trx->rsl_tei, SAPI_RSL);
if (!rsl_link) {
- LOGP(DINP, LOGL_ERROR, "TRX (%u/%u) RSL link creation "
+ LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) RSL link creation "
"failed\n", trx->bts->nr, trx->nr);
return -ENOMEM;
}
@@ -131,6 +132,33 @@ int e1_reconfig_trx(struct gsm_bts_trx *trx)
return 0;
}
+/* this is the generic callback for all ISDN-based BTS. */
+static int bts_isdn_sign_link(struct msgb *msg)
+{
+ int ret = -EINVAL;
+ struct e1inp_sign_link *link = msg->dst;
+ struct gsm_bts *bts;
+
+ log_set_context(BSC_CTX_BTS, link->trx->bts);
+ switch (link->type) {
+ case E1INP_SIGN_OML:
+ bts = link->trx->bts;
+ ret = bts->model->oml_rcvmsg(msg);
+ break;
+ case E1INP_SIGN_RSL:
+ ret = abis_rsl_rcvmsg(msg);
+ break;
+ default:
+ LOGP(DLMI, LOGL_ERROR, "unknown link type %u\n", link->type);
+ break;
+ }
+ return ret;
+}
+
+struct e1inp_line_ops bts_isdn_e1inp_line_ops = {
+ .sign_link = bts_isdn_sign_link,
+};
+
int e1_reconfig_bts(struct gsm_bts *bts)
{
struct gsm_e1_subslot *e1_link = &bts->oml_e1_link;
@@ -139,27 +167,40 @@ int e1_reconfig_bts(struct gsm_bts *bts)
struct e1inp_sign_link *oml_link;
struct gsm_bts_trx *trx;
- DEBUGP(DMI, "e1_reconfig_bts(%u)\n", bts->nr);
+ DEBUGP(DLMI, "e1_reconfig_bts(%u)\n", bts->nr);
- if (!e1_link->e1_ts) {
- LOGP(DINP, LOGL_ERROR, "BTS %u OML link without timeslot?\n",
- bts->nr);
+ line = e1inp_line_find(e1_link->e1_nr);
+ if (!line) {
+ LOGP(DLINP, LOGL_ERROR, "BTS %u OML link referring to "
+ "non-existing E1 line %u\n", bts->nr, e1_link->e1_nr);
+ return -ENOMEM;
+ }
+
+ if (!bts->model->e1line_bind_ops) {
+ LOGP(DLINP, LOGL_ERROR, "no callback to bind E1 line operations\n");
return -EINVAL;
}
+ if (!line->ops)
+ bts->model->e1line_bind_ops(line);
+
+ /* skip signal link initialization, this is done later for these BTS. */
+ if (bts->type == GSM_BTS_TYPE_NANOBTS ||
+ bts->type == GSM_BTS_TYPE_HSL_FEMTO)
+ return e1inp_line_update(line);
/* OML link */
- line = e1inp_line_get(e1_link->e1_nr);
- if (!line) {
- LOGP(DINP, LOGL_ERROR, "BTS %u OML link referring to "
- "non-existing E1 line %u\n", bts->nr, e1_link->e1_nr);
- return -ENOMEM;
+ if (!e1_link->e1_ts) {
+ LOGP(DLINP, LOGL_ERROR, "BTS %u OML link without timeslot?\n",
+ bts->nr);
+ return -EINVAL;
}
+
sign_ts = &line->ts[e1_link->e1_ts-1];
- e1inp_ts_config(sign_ts, line, E1INP_TS_TYPE_SIGN);
+ e1inp_ts_config_sign(sign_ts, line);
oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,
bts->c0, bts->oml_tei, SAPI_OML);
if (!oml_link) {
- LOGP(DINP, LOGL_ERROR, "BTS %u OML link creation failed\n",
+ LOGP(DLINP, LOGL_ERROR, "BTS %u OML link creation failed\n",
bts->nr);
return -ENOMEM;
}
@@ -260,37 +301,3 @@ int e1_config(struct gsm_bts *bts, int cardnr, int release_l2)
return mi_setup(cardnr, line, release_l2);
}
#endif
-
-/* configure pseudo E1 line in ip.access style and connect to BTS */
-int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin)
-{
- struct e1inp_line *line;
- struct e1inp_ts *sign_ts, *rsl_ts;
- struct e1inp_sign_link *oml_link, *rsl_link;
-
- line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
- if (!line)
- return -ENOMEM;
-
- /* create E1 timeslots for signalling and TRAU frames */
- e1inp_ts_config(&line->ts[1-1], line, E1INP_TS_TYPE_SIGN);
- e1inp_ts_config(&line->ts[2-1], line, E1INP_TS_TYPE_SIGN);
-
- /* create signalling links for TS1 */
- sign_ts = &line->ts[1-1];
- rsl_ts = &line->ts[2-1];
- oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,
- bts->c0, 0xff, 0);
- rsl_link = e1inp_sign_link_create(rsl_ts, E1INP_SIGN_RSL,
- bts->c0, 0, 0);
-
- /* create back-links from bts/trx */
- bts->oml_link = oml_link;
- bts->c0->rsl_link = rsl_link;
-
- /* default port at BTS for incoming connections is 3006 */
- if (sin->sin_port == 0)
- sin->sin_port = htons(3006);
-
- return ipaccess_connect(line, sin);
-}