diff options
Diffstat (limited to 'openbsc/src/libbsc')
-rw-r--r-- | openbsc/src/libbsc/abis_rsl.c | 52 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_vty.c | 2 | ||||
-rw-r--r-- | openbsc/src/libbsc/chan_alloc.c | 12 | ||||
-rw-r--r-- | openbsc/src/libbsc/gsm_04_08_utils.c | 6 |
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, |