aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/chan_alloc.h1
-rw-r--r--openbsc/src/bsc_init.c29
-rw-r--r--openbsc/src/chan_alloc.c14
3 files changed, 42 insertions, 2 deletions
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index f564e9e4d..d4f5858b7 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -45,6 +45,7 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
/* Free a logical channel (SDCCH, TCH, ...) */
void lchan_free(struct gsm_lchan *lchan);
+void lchan_reset(struct gsm_lchan *lchan);
/* Consider releasing the channel */
int lchan_auto_release(struct gsm_lchan *lchan);
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index f3436621f..fccdb0cd8 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -31,6 +31,7 @@
#include <openbsc/system_information.h>
#include <openbsc/paging.h>
#include <openbsc/signal.h>
+#include <openbsc/chan_alloc.h>
#include <osmocore/talloc.h>
/* global pointer to the gsm network data structure */
@@ -899,6 +900,8 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx)
void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
{
+ int ts_no, lchan_no;
+
switch (event) {
case EVT_E1_TEI_UP:
switch (type) {
@@ -913,8 +916,30 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
}
break;
case EVT_E1_TEI_DN:
- LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n");
- /* FIXME: deal with TEI or L1 link loss */
+ LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx);
+
+ /*
+ * free all allocated channels. change the nm_state so the
+ * trx and trx_ts becomes unusable and chan_alloc.c can not
+ * allocate from it.
+ */
+ for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
+
+ for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
+ if (ts->lchan[lchan_no].state != GSM_LCHAN_NONE)
+ lchan_free(&ts->lchan[lchan_no]);
+ lchan_reset(&ts->lchan[lchan_no]);
+ }
+
+ ts->nm_state.operational = 0;
+ ts->nm_state.availability = 0;
+ }
+
+ trx->nm_state.operational = 0;
+ trx->nm_state.availability = 0;
+ trx->bb_transc.nm_state.operational = 0;
+ trx->bb_transc.nm_state.availability = 0;
break;
default:
break;
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index 118deca10..107abdc92 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -330,6 +330,20 @@ void lchan_free(struct gsm_lchan *lchan)
* channel using it */
}
+/*
+ * There was an error with the TRX and we need to forget
+ * any state so that a lchan can be allocated again after
+ * the trx is fully usable.
+ */
+void lchan_reset(struct gsm_lchan *lchan)
+{
+ bsc_del_timer(&lchan->T3101);
+
+ lchan->type = GSM_LCHAN_NONE;
+ lchan->state = LCHAN_S_NONE;
+}
+
+
/* Consider releasing the channel now */
int lchan_auto_release(struct gsm_lchan *lchan)
{