aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libbsc')
-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
4 files changed, 54 insertions, 18 deletions
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,