summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-12-27 22:24:17 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-12-23 20:18:18 +0100
commit8582535c829e6a40591448e4b794af8fb022624e (patch)
treef4b9cf4116e054bb8cc03d72efda40328c0b17e3
parent960c4044e61c8b4a522649c5d0e8f29b777356a6 (diff)
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
-rw-r--r--openbsc/doc/channel_release.txt19
-rw-r--r--openbsc/include/openbsc/abis_rsl.h5
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h3
-rw-r--r--openbsc/src/libbsc/abis_rsl.c30
-rw-r--r--openbsc/src/libbsc/chan_alloc.c61
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 <laforge@gnumonks.org>
+ * (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;
}