From 6f6cbf7c5dedfd6335024004b1d21809e806a40d Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 4 Apr 2015 19:35:22 +0200 Subject: [PATCH] bts: "Repair" broken channels if we receive the release ack We had issues with odd behavior on the nanoBTS which lead to the introduction of the "broken" state. On busy multi BTS cells (e.g. rhizomatica) with wifi backhaul the timeout we set to wait for a RF Channe Release ACK is sometimes too little and channels are marked broken that look to be okay (besides the still to be determined delay). In case of a sysmoBTS we now know that we can change the state of a broken channel back to normal in case we do receive the right response. Manually verified using the Smalltalk BTS code PackageLoader fileInPackage: 'FakeBTS' bts := FakeBTS.BTS new. bts btsId: '1903/0/0'. bts connect: 'localhost'. bts waitForBTSReady. test := FakeBTS.OpenBSCTest new. test bts: bts. test requireAnyChannel ... wait for NITB output <0004> abis_rsl.c:223 (bts=0,trx=0,ts=0,ss=0) Timeout during deactivation! Marked as broken. ... process pending messages stdin next <0004> abis_rsl.c:735 (bts=0,trx=0,ts=0,ss=0) CHAN REL ACK for broken channel. Releasing it. So the channel went from broken to unallocated. --- openbsc/include/openbsc/gsm_data.h | 11 +++++++++++ openbsc/src/libbsc/abis_rsl.c | 17 ++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index bf1ac7c3a..51d68d23b 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -359,6 +359,17 @@ static inline int is_ipaccess_bts(struct gsm_bts *bts) return 0; } +static inline int is_sysmobts_v2(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_OSMO_SYSMO: + return 1; + default: + break; + } + return 0; +} + static inline int is_siemens_bts(struct gsm_bts *bts) { switch (bts->type) { diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 3fa30d112..41289ddd8 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -720,10 +720,21 @@ static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan) osmo_timer_del(&lchan->act_timer); osmo_timer_del(&lchan->T3111); + /* + * The BTS didn't respond within the timeout to our channel + * release request and we have marked the channel as broken. + * Now we do receive an ACK and let's be conservative. If it + * is a sysmoBTS we know that only one RF Channel Release ACK + * will be sent. So let's "repair" the channel. + */ if (lchan->state == LCHAN_S_BROKEN) { - /* we are leaving this channel broken for now */ - LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK for broken channel.\n", - gsm_lchan_name(lchan)); + int do_free = is_sysmobts_v2(lchan->ts->trx->bts); + LOGP(DRSL, LOGL_NOTICE, + "%s CHAN REL ACK for broken channel. %s.\n", + gsm_lchan_name(lchan), + do_free ? "Releasing it" : "Keeping it broken"); + if (do_free) + do_lchan_free(lchan); return 0; }