aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-12-28 16:21:05 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-12-23 20:20:38 +0100
commitb348939d86bbadab2b162dda00246abdfd33055a (patch)
tree4989a09e50b3153cb844552c1ac28b46e977aeaf
parent638da51a786c279cf7769afbb6fdb56cc4c6c867 (diff)
lchan: Introduce T3109 handling for the release procedure
T3109 is started when the SACCH is deactivated. It is stopped when the phones sends the DISC/UA/UM on LAPDm for the main signalling link. In case of timeout the abnormal release procedure will be initiated. Make sure to not issue the SACCH Deactivate twice to avoid confusing the equipment. This is still not fully spec compliant. In case of a timeout the abnormal release handling will be started which involves starting T3111+2. The error handling should be split out of the rf channel release method, e.g. lchan_release should be called and check if the channel release was already initiated.
-rw-r--r--openbsc/doc/channel_release.txt3
-rw-r--r--openbsc/doc/examples/osmo-nitb/bs11/openbsc-1bts-2trx-hopping.cfg2
-rw-r--r--openbsc/doc/examples/osmo-nitb/hsl/openbsc.cfg2
-rw-r--r--openbsc/doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg2
-rw-r--r--openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg2
-rw-r--r--openbsc/doc/examples/osmo-nitb/rbs2308/openbsc.cfg2
-rw-r--r--openbsc/include/openbsc/abis_rsl.h1
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h1
-rw-r--r--openbsc/src/libbsc/abis_rsl.c52
-rw-r--r--openbsc/src/libbsc/bsc_vty.c2
-rw-r--r--openbsc/src/libbsc/chan_alloc.c12
-rw-r--r--openbsc/src/libbsc/gsm_04_08_utils.c6
12 files changed, 63 insertions, 24 deletions
diff --git a/openbsc/doc/channel_release.txt b/openbsc/doc/channel_release.txt
index bd707b451..c9cdfebca 100644
--- a/openbsc/doc/channel_release.txt
+++ b/openbsc/doc/channel_release.txt
@@ -61,7 +61,8 @@ chan_alloc.c:lchan_release(chan, sacch_deactivate, reason)
* 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.
+ * Start T3109 (stop it when the main signalling link is disconnected)
+ or when the channel released. On timeout start the error handling.
* 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.
diff --git a/openbsc/doc/examples/osmo-nitb/bs11/openbsc-1bts-2trx-hopping.cfg b/openbsc/doc/examples/osmo-nitb/bs11/openbsc-1bts-2trx-hopping.cfg
index 654d39716..36065e254 100644
--- a/openbsc/doc/examples/osmo-nitb/bs11/openbsc-1bts-2trx-hopping.cfg
+++ b/openbsc/doc/examples/osmo-nitb/bs11/openbsc-1bts-2trx-hopping.cfg
@@ -30,7 +30,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
- timer t3109 0
+ timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0
diff --git a/openbsc/doc/examples/osmo-nitb/hsl/openbsc.cfg b/openbsc/doc/examples/osmo-nitb/hsl/openbsc.cfg
index 3d95748a3..b0af85598 100644
--- a/openbsc/doc/examples/osmo-nitb/hsl/openbsc.cfg
+++ b/openbsc/doc/examples/osmo-nitb/hsl/openbsc.cfg
@@ -31,7 +31,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
- timer t3109 0
+ timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0
diff --git a/openbsc/doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg b/openbsc/doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg
index 7a187f881..bea0b7dfc 100644
--- a/openbsc/doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg
+++ b/openbsc/doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg
@@ -30,7 +30,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
- timer t3109 0
+ timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0
diff --git a/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg b/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg
index 78e9787b9..7a443087c 100644
--- a/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg
+++ b/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg
@@ -30,7 +30,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
- timer t3109 0
+ timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0
diff --git a/openbsc/doc/examples/osmo-nitb/rbs2308/openbsc.cfg b/openbsc/doc/examples/osmo-nitb/rbs2308/openbsc.cfg
index 7135042ff..97cd9df50 100644
--- a/openbsc/doc/examples/osmo-nitb/rbs2308/openbsc.cfg
+++ b/openbsc/doc/examples/osmo-nitb/rbs2308/openbsc.cfg
@@ -29,7 +29,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
- timer t3109 0
+ timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index 45af4a6fc..4f2b6b551 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -99,6 +99,7 @@ int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduc
int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
enum rsl_rel_mode release_mode);
+int rsl_start_t3109(struct gsm_lchan *lchan);
#endif /* RSL_MT_H */
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 21fa6456a..ba431da03 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -217,6 +217,7 @@ struct gsm_lchan {
#ifdef ROLE_BSC
struct osmo_timer_list T3101;
+ struct osmo_timer_list T3109;
struct osmo_timer_list T3111;
struct osmo_timer_list error_timer;
struct osmo_timer_list act_timer;
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index 04d5c61b3..6e1ce7852 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -46,6 +46,11 @@
#define RSL_ALLOC_SIZE 1024
#define RSL_ALLOC_HEADROOM 128
+enum sacch_deact {
+ SACCH_NONE,
+ SACCH_DEACTIVATE,
+};
+
static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
@@ -644,12 +649,16 @@ static void error_timeout_cb(void *data)
static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
-static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
+static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
+ enum sacch_deact deact_sacch)
{
struct abis_rsl_dchan_hdr *dh;
struct msgb *msg;
int rc;
+ /* Stop timers that should lead to a channel release */
+ osmo_timer_del(&lchan->T3109);
+
if (lchan->state == LCHAN_S_REL_ERR) {
LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
gsm_lchan_name(lchan));
@@ -688,7 +697,8 @@ static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
/*
* sacch de-activate and "local end release"
*/
- rsl_deact_sacch(lchan);
+ if (deact_sacch == SACCH_DEACTIVATE)
+ rsl_deact_sacch(lchan);
rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
/*
@@ -939,7 +949,7 @@ static int rsl_rx_chan_act_nack(struct msgb *msg)
if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
else
- rsl_rf_chan_release(msg->lchan, 1);
+ rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
} else
rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
@@ -969,7 +979,7 @@ static int rsl_rx_conn_fail(struct msgb *msg)
LOGPC(DRSL, LOGL_NOTICE, "\n");
/* FIXME: only free it after channel release ACK */
osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
- return rsl_rf_chan_release(msg->lchan, 1);
+ return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
}
static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
@@ -1250,7 +1260,7 @@ static void t3101_expired(void *data)
{
struct gsm_lchan *lchan = data;
- rsl_rf_chan_release(lchan, 1);
+ rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
}
/* If T3111 expires, we will send the RF Channel Request */
@@ -1258,7 +1268,17 @@ static void t3111_expired(void *data)
{
struct gsm_lchan *lchan = data;
- rsl_rf_chan_release(lchan, 0);
+ rsl_rf_chan_release(lchan, 0, SACCH_NONE);
+}
+
+/* If T3109 expires the MS has not send a UA/UM do the error release */
+static void t3109_expired(void *data)
+{
+ struct gsm_lchan *lchan = data;
+
+ LOGP(DRSL, LOGL_ERROR,
+ "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
+ rsl_rf_chan_release(lchan, 1, SACCH_NONE);
}
#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
@@ -1516,7 +1536,7 @@ static int rsl_rx_rll_err_ind(struct msgb *msg)
if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
- return rsl_rf_chan_release(msg->lchan, 1);
+ return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
}
return 0;
@@ -1544,8 +1564,8 @@ static void rsl_handle_release(struct gsm_lchan *lchan)
}
-
- /* wait a bit to send the RF Channel Release */
+ /* Stop T3109 and wait for T3111 before re-using the channel */
+ osmo_timer_del(&lchan->T3109);
lchan->T3111.cb = t3111_expired;
lchan->T3111.data = lchan;
bts = lchan->ts->trx->bts;
@@ -2107,3 +2127,17 @@ int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
return no_sapi;
}
+
+int rsl_start_t3109(struct gsm_lchan *lchan)
+{
+ struct gsm_bts *bts = lchan->ts->trx->bts;
+
+ /* Disabled, mostly legacy code */
+ if (bts->network->T3109 == 0)
+ return -1;
+
+ lchan->T3109.cb = t3109_expired;
+ lchan->T3109.data = lchan;
+ osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
+ return 0;
+}
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 61b091120..dfe80c9e7 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -1379,7 +1379,7 @@ DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT.\n")
DECLARE_TIMER(3103, "Set the timeout value for HANDOVER.\n")
DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION.\n")
DECLARE_TIMER(3107, "Currently not used.\n")
-DECLARE_TIMER(3109, "Currently not used.\n")
+DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout.\n")
DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel.\n")
DECLARE_TIMER(3113, "Set the time to try paging a subscriber.\n")
DECLARE_TIMER(3115, "Currently not used.\n")
diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c
index a8b15d177..9b59d5df0 100644
--- a/openbsc/src/libbsc/chan_alloc.c
+++ b/openbsc/src/libbsc/chan_alloc.c
@@ -362,6 +362,7 @@ void lchan_free(struct gsm_lchan *lchan)
void lchan_reset(struct gsm_lchan *lchan)
{
osmo_timer_del(&lchan->T3101);
+ osmo_timer_del(&lchan->T3109);
osmo_timer_del(&lchan->T3111);
osmo_timer_del(&lchan->error_timer);
@@ -376,7 +377,7 @@ void lchan_reset(struct gsm_lchan *lchan)
/* Drive the release process of the lchan */
static void _lchan_handle_release(struct gsm_lchan *lchan,
- int sach_deact, int mode)
+ int sacch_deact, int mode)
{
/* Release all SAPIs on the local end and continue */
rsl_release_sapis_from(lchan, 1, RSL_REL_LOCAL_END);
@@ -386,10 +387,15 @@ static void _lchan_handle_release(struct gsm_lchan *lchan,
* release indication from the BTS or just take it down (e.g.
* on assignment requests)
*/
- if (sach_deact)
+ if (sacch_deact) {
gsm48_send_rr_release(lchan);
- else
+
+ /* Deactivate the SACCH on the BTS side */
+ rsl_deact_sacch(lchan);
+ rsl_start_t3109(lchan);
+ } else {
rsl_release_request(lchan, 0, mode);
+ }
}
/* Consider releasing the channel now */
diff --git a/openbsc/src/libbsc/gsm_04_08_utils.c b/openbsc/src/libbsc/gsm_04_08_utils.c
index 968e62ec6..de596de09 100644
--- a/openbsc/src/libbsc/gsm_04_08_utils.c
+++ b/openbsc/src/libbsc/gsm_04_08_utils.c
@@ -231,11 +231,7 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan)
lchan->nr, lchan->type);
/* Send actual release request to MS */
- gsm48_sendmsg(msg);
- /* FIXME: Start Timer T3109 */
-
- /* Deactivate the SACCH on the BTS side */
- return rsl_deact_sacch(lchan);
+ return gsm48_sendmsg(msg);
}
int send_siemens_mrpci(struct gsm_lchan *lchan,