diff options
author | Pablo Neira Ayuso <pablo@gnumonks.org> | 2011-08-17 22:44:07 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-08-19 22:38:35 +0200 |
commit | ed5cacb240b846c106f0fc6a3ab8e8721f4c70a5 (patch) | |
tree | ba6bffbf0c95ecc0c50b5335bed77f3a2b29120f /openbsc/src/libbsc | |
parent | 7abecfcfc9ef94c1367cd88ac858b79d20f75db0 (diff) |
src: port openBSC over libosmo-abisopenbsc/0.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.c | 24 | ||||
-rw-r--r-- | openbsc/src/libbsc/abis_om2000.c | 2 | ||||
-rw-r--r-- | openbsc/src/libbsc/abis_rsl.c | 2 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_init.c | 21 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_msc.c | 4 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_vty.c | 33 | ||||
-rw-r--r-- | openbsc/src/libbsc/bts_ericsson_rbs2000.c | 26 | ||||
-rw-r--r-- | openbsc/src/libbsc/bts_hsl_femtocell.c | 155 | ||||
-rw-r--r-- | openbsc/src/libbsc/bts_ipaccess_nanobts.c | 194 | ||||
-rw-r--r-- | openbsc/src/libbsc/bts_nokia_site.c | 52 | ||||
-rw-r--r-- | openbsc/src/libbsc/bts_siemens_bs11.c | 18 | ||||
-rw-r--r-- | openbsc/src/libbsc/e1_config.c | 125 |
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); -} |