aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}