diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-04-15 11:21:02 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-04-15 11:24:53 +0200 |
commit | 135f797a3711d317a9aef43f0efa9fb8764a0d10 (patch) | |
tree | 0c4401814e1e95462d6de083a2c4622fa991343f /openbsc/src/bsc_init.c | |
parent | f8eff2e4b537c00cfc8a17991759df0f58a29148 (diff) |
[bsc_init] When the RSL/OML connection drops, free all lchans
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) which should be reset once the
RSL is coming up again.
Diffstat (limited to 'openbsc/src/bsc_init.c')
-rw-r--r-- | openbsc/src/bsc_init.c | 29 |
1 files changed, 27 insertions, 2 deletions
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; |