aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-02-05 09:06:49 +0100
committerHarald Welte <laforge@gnumonks.org>2013-03-11 11:47:41 +0100
commit294fd1b650e4482775fdd604288fc928e66ef81c (patch)
tree506a480f0f000d7cea082e104d39cc5873164a5c
parent19f212951af720bc5ad415d8347838f3ac222442 (diff)
Added radio link timeout procedure according to TS 05.08 Chapter 5.2
Chapter 5.2 applies to MS procedure, but 5.3 (BSS procedure) defines no exact criterion, so I decided to use the procedure equivalent to MS. The criterion is based on a counter S, which is initialized to a preset RADIO_LINK_TIMEOUT, which can be configured via VTY. Whenever a received SACCH block is bad, S is counted down by one. If SACCH block is successfully decoded, S is counted up by two, but never above initial RADIO_LINK_TIMEOUT value. If S reaches 0, an RSL Connection Failure Indication with cause RF Radio Link Failure is sent to BSC, which then aborts channel. Use link timeout value from BSC via OML attribute. How to test: - Set "debug" for "meas" logging. - Start silent call to an attached mobile. - Remove battery from mobile or shield mobile. - Watch S count down.
-rw-r--r--include/osmo-bts/gsm_data.h1
-rw-r--r--include/osmo-bts/rsl.h1
-rw-r--r--src/common/bts.c3
-rw-r--r--src/common/oml.c9
-rw-r--r--src/common/rsl.c20
-rw-r--r--src/osmo-bts-sysmo/l1_if.c27
-rw-r--r--src/osmo-bts-sysmo/oml.c3
7 files changed, 61 insertions, 3 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index 267aa52b..bf2d172c 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -58,6 +58,7 @@ struct gsm_bts_role_bts {
struct {
uint8_t tc4_ctr;
} si;
+ uint8_t radio_link_timeout;
};
enum lchan_ciph_state {
diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h
index c8daff32..251cd23d 100644
--- a/include/osmo-bts/rsl.h
+++ b/include/osmo-bts/rsl.h
@@ -9,6 +9,7 @@ int rsl_tx_est_ind(struct gsm_lchan *lchan, uint8_t link_id, uint8_t *data, int
int rsl_tx_chan_act_ack(struct gsm_lchan *lchan, struct gsm_time *gtime);
int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause);
+int rsl_tx_conn_fail(struct gsm_lchan *lchan, uint8_t cause);
int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan);
/* call-back for LAPDm code, called when it wants to send msgs UP */
diff --git a/src/common/bts.c b/src/common/bts.c
index db58e12f..8cb64c46 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -75,6 +75,9 @@ int bts_init(struct gsm_bts *bts)
btsb->rtp_jitter_buf_ms = 100;
btsb->max_ta = 63;
+ /* default RADIO_LINK_TIMEOUT */
+ btsb->radio_link_timeout = 32;
+
/* set BTS to dependency */
oml_mo_state_chg(&bts->mo, -1, NM_AVSTATE_DEPENDENCY);
oml_mo_state_chg(&bts->gprs.nse.mo, -1, NM_AVSTATE_DEPENDENCY);
diff --git a/src/common/oml.c b/src/common/oml.c
index 055ef032..4e2deadb 100644
--- a/src/common/oml.c
+++ b/src/common/oml.c
@@ -446,7 +446,14 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
btsb->interference.intave = *TLVP_VAL(&tp, NM_ATT_INTAVE_PARAM);
/* 9.4.14 Connection Failure Criterion */
- /* ... can be 'operator dependent' and needs to be parsed by bts driver */
+ if (TLVP_PRESENT(&tp, NM_ATT_CONN_FAIL_CRIT) &&
+ (TLVP_LEN(&tp, NM_ATT_CONN_FAIL_CRIT) >= 2) &&
+ *TLVP_VAL(&tp, NM_ATT_CONN_FAIL_CRIT) == 0x01) {
+ const uint8_t *val = TLVP_VAL(&tp, NM_ATT_CONN_FAIL_CRIT);
+ btsb->radio_link_timeout = val[1];
+ }
+ /* if val[0] != 0x01: can be 'operator dependent' and needs to
+ * be parsed by bts driver */
/* 9.4.53 T200 */
if (TLVP_PRESENT(&tp, NM_ATT_T200)) {
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 5f2dd901..2aec0cee 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -541,6 +541,26 @@ int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause)
return abis_rsl_sendmsg(msg);
}
+/* 8.4.4 sending CONNection FAILure */
+int rsl_tx_conn_fail(struct gsm_lchan *lchan, uint8_t cause)
+{
+ struct msgb *msg;
+ uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
+
+ LOGP(DRSL, LOGL_NOTICE, "Sending Connection Failure: cause = 0x%02x\n", cause);
+
+ msg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr));
+ if (!msg)
+ return -ENOMEM;
+
+ /* 9.3.26 Cause */
+ msgb_tlv_put(msg, RSL_IE_CAUSE, 1, &cause);
+ rsl_dch_push_hdr(msg, RSL_MT_CONN_FAIL, chan_nr);
+ msg->trx = lchan->ts->trx;
+
+ return abis_rsl_sendmsg(msg);
+}
+
/* 8.5.3 sending CHANnel ReQuireD */
int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime,
uint8_t ra, uint8_t acc_delay)
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 9b05267f..df660c5f 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -42,6 +42,7 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/oml.h>
+#include <osmo-bts/rsl.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/paging.h>
#include <osmo-bts/measurement.h>
@@ -650,6 +651,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
struct msgb *l1p_msg)
{
struct gsm_bts_trx *trx = fl1->priv;
+ struct gsm_bts_role_bts *btsb = trx->bts->role;
struct osmo_phsap_prim pp;
struct gsm_lchan *lchan;
struct lapdm_entity *le;
@@ -666,7 +668,8 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
process_meas_res(lchan, &data_ind->measParam);
- if (data_ind->measParam.fLinkQuality < MIN_QUAL_NORM)
+ if (data_ind->measParam.fLinkQuality < MIN_QUAL_NORM
+ && data_ind->msgUnitParam.u8Size != 0)
return 0;
DEBUGP(DL1C, "Rx PH-DATA.ind %s (hL2 %08x): %s",
@@ -678,6 +681,25 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
switch (data_ind->sapi) {
case GsmL1_Sapi_Sacch:
+ /* process radio link timeout coniter S */
+ if (data_ind->msgUnitParam.u8Size == 0) {
+ /* count down radio link counter S */
+ lchan->s--;
+ DEBUGP(DMEAS, "counting down radio link counter S=%d\n",
+ lchan->s);
+ if (lchan->s == 0)
+ rsl_tx_conn_fail(lchan,
+ RSL_ERR_RADIO_LINK_FAIL);
+ break;
+ }
+ if (lchan->s < btsb->radio_link_timeout) {
+ /* count up radio link counter S */
+ lchan->s += 2;
+ if (lchan->s > btsb->radio_link_timeout)
+ lchan->s = btsb->radio_link_timeout;
+ DEBUGP(DMEAS, "counting up radio link counter S=%d\n",
+ lchan->s);
+ }
/* save the SACCH L1 header in the lchan struct for RSL MEAS RES */
if (data_ind->msgUnitParam.u8Size < 2) {
LOGP(DL1C, LOGL_NOTICE, "SACCH with size %u<2 !?!\n",
@@ -744,7 +766,8 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
case GsmL1_Sapi_Pdtch:
case GsmL1_Sapi_Pacch:
/* drop incomplete UL block */
- if (data_ind->msgUnitParam.u8Buffer[0]
+ if (!data_ind->msgUnitParam.u8Size
+ || data_ind->msgUnitParam.u8Buffer[0]
!= GsmL1_PdtchPlType_Full)
break;
/* PDTCH / PACCH frame handling */
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index 9e2ac8ee..da3b95b5 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -718,6 +718,7 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, int sapi, int dir)
int lchan_activate(struct gsm_lchan *lchan)
{
+ struct gsm_bts_role_bts *btsb = lchan->ts->trx->bts->role;
struct femtol1_hdl *fl1h = trx_femtol1_hdl(lchan->ts->trx);
const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type];
unsigned int i;
@@ -740,6 +741,8 @@ int lchan_activate(struct gsm_lchan *lchan)
lchan_init_lapdm(lchan);
+ lchan->s = btsb->radio_link_timeout;
+
return 0;
}