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.c15
3 files changed, 43 insertions, 2 deletions
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index 2cf447c7f..d9152c61b 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -67,6 +67,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);
/* internal.. do not use */
int _lchan_release(struct gsm_lchan *lchan, u_int8_t release_reason);
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index 5ef22db40..78b575302 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 */
@@ -901,6 +902,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) {
@@ -915,8 +918,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 48732f76c..1fb0a4f1e 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -322,6 +322,21 @@ 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);
+ bsc_del_timer(&lchan->T3111);
+ bsc_del_timer(&lchan->error_timer);
+
+ lchan->type = GSM_LCHAN_NONE;
+ lchan->state = LCHAN_S_NONE;
+}
+
static int _lchan_release_next_sapi(struct gsm_lchan *lchan)
{
int sapi;