From 4e23d5f87f4443c5cf01cda968c1aae26ba47dc0 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 11 Apr 2010 19:34:43 +0200 Subject: [bsc_init] When the RSL/OML connection drops, free all lchan Free all allocated channels on the TRX that failed, go through lchan_free to signal higher layers and then force a reset of the channel. Make the TRX and TS unusable by setting the operational set to 0 (not really defined). --- openbsc/include/openbsc/chan_alloc.h | 1 + openbsc/src/bsc_init.c | 29 +++++++++++++++++++++++++++-- openbsc/src/chan_alloc.c | 15 +++++++++++++++ 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 #include #include +#include #include /* 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; -- cgit v1.2.3