From 8582535c829e6a40591448e4b794af8fb022624e Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 27 Dec 2011 22:24:17 +0100 Subject: lchan: Release the lchan more quickly, align with GSM 04.08 * Release all channels with SAPI > 0 with the "local end release" (as of NOTE 1 of GSM 04.08). * No need to wait for all SAPIs to be torn down and the normal REL_IND/REL_CONF will call rsl_handle_release and the channel should be released. * Update the documentation --- openbsc/doc/channel_release.txt | 19 +++++----- openbsc/include/openbsc/abis_rsl.h | 5 ++- openbsc/include/openbsc/gsm_data_shared.h | 3 -- openbsc/src/libbsc/abis_rsl.c | 30 ++++++++++++++- openbsc/src/libbsc/chan_alloc.c | 61 +++++++------------------------ 5 files changed, 55 insertions(+), 63 deletions(-) diff --git a/openbsc/doc/channel_release.txt b/openbsc/doc/channel_release.txt index e578aa828..bd707b451 100644 --- a/openbsc/doc/channel_release.txt +++ b/openbsc/doc/channel_release.txt @@ -56,21 +56,20 @@ bsc_api.c:gsm0808_clear * Release the primary lchan with normal release, SACH deactivate chan_alloc.c:lchan_release(chan, sacch_deactivate, reason) - * Start release procedure. It is working in steps with callbacks - coming from the abis_rsl.c code. - * Release all SAPI's > 0, wait for them to be released - * Send SACH Deactivate on SAPI=0 - * Finally Release the channel + * Start the release procedure. It is working in steps with callbacks + coming from the abis_rsl.c code. + * Release all SAPI's > 0 as local end (The BTS should send a + REL_CONF a message) + * Send SACH Deactivate on SAPI=0 if required. + * It should start T3109 but it does not. + * abis_rsl.c schedules the RSL_MT_RF_CHAN_REL once all SAPI's are + released and after T3111 has timed out or there is an error. RX of RELease INDication: * Calls internal rsl_handle_release which might release the RF. - * Informs chan_alloc.c about the release with - rsl_lchan_rll_release. -RX of RELease CONFimem: +RX of RELease CONFirmation: * Calls internal rsl_handle_release which might release the RF. - * Informs chan_alloc.c about the release with - rsl_lchan_rll_release. * RX of RF_CHAN_REL_ACK * call lchan_free() diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h index c34492e09..45af4a6fc 100644 --- a/openbsc/include/openbsc/abis_rsl.h +++ b/openbsc/include/openbsc/abis_rsl.h @@ -74,7 +74,6 @@ int rsl_lchan_set_state(struct gsm_lchan *lchan, int); /* to be provided by external code */ int rsl_deact_sacch(struct gsm_lchan *lchan); -int rsl_lchan_rll_release(struct gsm_lchan *lchan, uint8_t link_id); /* BCCH related code */ int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf); @@ -97,5 +96,9 @@ int rsl_nokia_si_end(struct gsm_bts_trx *trx); /* required for Nokia BTS power control */ int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction); + +int rsl_release_sapis_from(struct gsm_lchan *lchan, int start, + enum rsl_rel_mode release_mode); + #endif /* RSL_MT_H */ diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index f81280f92..27bbe5c9b 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -196,9 +196,6 @@ struct gsm_lchan { uint8_t sapis[8]; int sacch_deact; - /* Release handling */ - enum rsl_rel_mode release_mode; - struct { uint32_t bound_ip; uint32_t connect_ip; diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 6f50cee16..6785be2e8 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -2,6 +2,7 @@ * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */ /* (C) 2008-2010 by Harald Welte + * (C) 2012 by Holger Hans Peter Freyther * * All Rights Reserved * @@ -1581,7 +1582,6 @@ static int abis_rsl_rx_rll(struct msgb *msg) rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_REL_IND); rsl_handle_release(msg->lchan); - rsl_lchan_rll_release(msg->lchan, rllh->link_id); break; case RSL_MT_REL_CONF: /* BTS informs us of having received UA from MS, @@ -1589,7 +1589,6 @@ static int abis_rsl_rx_rll(struct msgb *msg) DEBUGPC(DRLL, "RELEASE CONFIRMATION\n"); msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED; rsl_handle_release(msg->lchan); - rsl_lchan_rll_release(msg->lchan, rllh->link_id); break; case RSL_MT_ERROR_IND: rc = rsl_rx_rll_err_ind(msg); @@ -2058,3 +2057,30 @@ int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduc return abis_rsl_sendmsg(msg); } + +/** + * Release all allocated SAPIs starting from @param start and + * release them with the given release mode. Once the release + * confirmation arrives it will be attempted to release the + * the RF channel. + */ +int rsl_release_sapis_from(struct gsm_lchan *lchan, int start, + enum rsl_rel_mode release_mode) +{ + int no_sapi = 1; + int sapi; + + for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) { + uint8_t link_id; + if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) + continue; + + link_id = sapi; + if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H) + link_id |= 0x40; + rsl_release_request(lchan, link_id, release_mode); + no_sapi = 0; + } + + return no_sapi; +} diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c index 1efe2aac3..a8b15d177 100644 --- a/openbsc/src/libbsc/chan_alloc.c +++ b/openbsc/src/libbsc/chan_alloc.c @@ -345,8 +345,6 @@ void lchan_free(struct gsm_lchan *lchan) } lchan->sacch_deact = 0; - lchan->release_mode = RSL_REL_NORMAL; - /* FIXME: ts_free() the timeslot, if we're the last logical * channel using it */ } @@ -376,51 +374,22 @@ void lchan_reset(struct gsm_lchan *lchan) } } -/* release the next allocated SAPI or return 0 */ -static int _lchan_release_next_sapi(struct gsm_lchan *lchan) -{ - int sapi; - - for (sapi = 1; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) { - uint8_t link_id; - if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) - continue; - - link_id = sapi; - if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H) - link_id |= 0x40; - rsl_release_request(lchan, link_id, RSL_REL_LOCAL_END); - return 0; - } - - return 1; -} - /* Drive the release process of the lchan */ -static void _lchan_handle_release(struct gsm_lchan *lchan) +static void _lchan_handle_release(struct gsm_lchan *lchan, + int sach_deact, int mode) { - /* Ask for SAPI != 0 to be freed first and stop if we need to wait */ - if (_lchan_release_next_sapi(lchan) == 0) - return; - - if (lchan->sacch_deact) { + /* Release all SAPIs on the local end and continue */ + rsl_release_sapis_from(lchan, 1, RSL_REL_LOCAL_END); + + /* + * Shall we send a RR Release, start T3109 and wait for the + * release indication from the BTS or just take it down (e.g. + * on assignment requests) + */ + if (sach_deact) gsm48_send_rr_release(lchan); - return; - } - - rsl_release_request(lchan, 0, lchan->release_mode); - rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ); -} - -/* called from abis rsl */ -int rsl_lchan_rll_release(struct gsm_lchan *lchan, uint8_t link_id) -{ - if (lchan->state != LCHAN_S_REL_REQ) - return -1; - - if ((link_id & 0x7) != 0) - _lchan_handle_release(lchan); - return 0; + else + rsl_release_request(lchan, 0, mode); } /* Consider releasing the channel now */ @@ -430,9 +399,7 @@ int lchan_release(struct gsm_lchan *lchan, int sacch_deact, enum rsl_rel_mode mo rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ); lchan->conn = NULL; - lchan->release_mode = mode; - lchan->sacch_deact = sacch_deact; - _lchan_handle_release(lchan); + _lchan_handle_release(lchan, sacch_deact, mode); return 1; } -- cgit v1.2.3