summaryrefslogtreecommitdiffstats
path: root/src/libbsc/bts_ericsson_rbs2000.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libbsc/bts_ericsson_rbs2000.c')
-rw-r--r--src/libbsc/bts_ericsson_rbs2000.c121
1 files changed, 115 insertions, 6 deletions
diff --git a/src/libbsc/bts_ericsson_rbs2000.c b/src/libbsc/bts_ericsson_rbs2000.c
index 27d5ce6f7..9c98a9fef 100644
--- a/src/libbsc/bts_ericsson_rbs2000.c
+++ b/src/libbsc/bts_ericsson_rbs2000.c
@@ -19,13 +19,13 @@
*
*/
-#include <sys/types.h>
-#include <osmocore/tlv.h>
+#include <osmocom/gsm/tlv.h>
#include <openbsc/debug.h>
#include <openbsc/gsm_data.h>
#include <openbsc/abis_om2000.h>
+#include <openbsc/abis_nm.h>
#include <openbsc/e1_input.h>
#include <openbsc/signal.h>
@@ -40,9 +40,12 @@ static void bootstrap_om_bts(struct gsm_bts *bts)
static void bootstrap_om_trx(struct gsm_bts_trx *trx)
{
+ struct abis_om2k_mo trx_mo = { OM2K_MO_CLS_TRXC, 0, 255, trx->nr };
+
LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for TRX %u/%u\n",
trx->bts->nr, trx->nr);
- /* FIXME */
+
+ abis_om2k_tx_reset_cmd(trx->bts, &trx_mo);
}
static int shutdown_om(struct gsm_bts *bts)
@@ -137,19 +140,119 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
return 0;
}
+static void nm_statechg_evt(unsigned int signal,
+ struct nm_statechg_signal_data *nsd)
+{
+ struct abis_om2k_mo mo;
+
+ if (nsd->bts->type != GSM_BTS_TYPE_RBS2000)
+ return;
+
+ switch (nsd->om2k_mo->class) {
+ case OM2K_MO_CLS_CF:
+ if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
+ nsd->new_state->availability != OM2K_MO_S_STARTED)
+ break;
+ /* CF has started, we can trigger IS and TF start */
+ abis_om2k_tx_connect_cmd(nsd->bts, &om2k_mo_is);
+ abis_om2k_tx_connect_cmd(nsd->bts, &om2k_mo_tf);
+ break;
+ case OM2K_MO_CLS_IS:
+ if (nsd->new_state->availability == OM2K_MO_S_ENABLED) {
+ /* IS is enabled, we can proceed with TRXC/RX/TX/TS */
+ break;
+ }
+ if (nsd->new_state->operational != NM_OPSTATE_ENABLED)
+ break;
+ /* IS has started, we can configure + enable it */
+ abis_om2k_tx_is_conf_req(nsd->bts);
+ break;
+ case OM2K_MO_CLS_TF:
+ if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
+ nsd->new_state->availability == OM2K_MO_S_DISABLED)
+ break;
+ if (nsd->new_state->availability == OM2K_MO_S_STARTED) {
+ /* TF has started, configure + enable it */
+ abis_om2k_tx_is_conf_req(nsd->bts);
+ }
+ break;
+ case OM2K_MO_CLS_TRXC:
+ if (nsd->new_state->availability != OM2K_MO_S_STARTED)
+ break;
+ /* TRXC is started, connect the TX and RX objects */
+ memcpy(&mo, nsd->om2k_mo, sizeof(mo));
+ mo.class = OM2K_MO_CLS_TX;
+ abis_om2k_tx_connect_cmd(nsd->bts, &mo);
+ mo.class = OM2K_MO_CLS_RX;
+ abis_om2k_tx_connect_cmd(nsd->bts, &mo);
+ break;
+ case OM2K_MO_CLS_RX:
+ if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
+ nsd->new_state->availability != OM2K_MO_S_STARTED)
+ break;
+ /* RX is started, configure + enable it */
+ abis_om2k_tx_rx_conf_req(nsd->obj);
+ break;
+ case OM2K_MO_CLS_TX:
+ if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
+ nsd->new_state->availability != OM2K_MO_S_STARTED)
+ break;
+ /* RX is started, configure + enable it */
+ abis_om2k_tx_tx_conf_req(nsd->obj);
+ break;
+ }
+}
+
+static void nm_conf_res(struct nm_om2k_signal_data *nsd)
+{
+ switch (nsd->om2k_mo->class) {
+ case OM2K_MO_CLS_IS:
+ case OM2K_MO_CLS_TF:
+ case OM2K_MO_CLS_RX:
+ case OM2K_MO_CLS_TX:
+ /* If configuration was a success, enable it */
+ abis_om2k_tx_enable_req(nsd->bts, nsd->om2k_mo);
+ break;
+ }
+}
+
+static int nm_sig_cb(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data)
+{
+ if (subsys != SS_NM)
+ return 0;
+
+ switch (signal) {
+ case S_NM_STATECHG_OPER:
+ case S_NM_STATECHG_ADM:
+ nm_statechg_evt(signal, signal_data);
+ break;
+ case S_NM_OM2K_CONF_RES:
+ nm_conf_res(signal_data);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static void config_write_bts(struct vty *vty, struct gsm_bts *bts)
{
abis_om2k_config_write_bts(vty, bts);
}
+static int bts_model_rbs2k_start(struct gsm_network *net);
+
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,
};
-int bts_model_rbs2k_init(void)
+static int bts_model_rbs2k_start(struct gsm_network *net)
{
model_rbs2k.features.data = &model_rbs2k._features_data[0];
model_rbs2k.features.data_len = sizeof(model_rbs2k._features_data);
@@ -157,8 +260,14 @@ int bts_model_rbs2k_init(void)
gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_HOPPING);
gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_HSCSD);
- register_signal_handler(SS_INPUT, inp_sig_cb, NULL);
- register_signal_handler(SS_GLOBAL, gbl_sig_cb, NULL);
+ 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_NM, nm_sig_cb, NULL);
+
+ return 0;
+}
+int bts_model_rbs2k_init(void)
+{
return gsm_bts_model_register(&model_rbs2k);
}