aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h14
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h2
-rw-r--r--openbsc/src/libbsc/bsc_vty.c29
-rw-r--r--openbsc/src/libbsc/bts_ipaccess_nanobts_omlattr.c14
-rw-r--r--openbsc/src/libcommon/gsm_data.c40
6 files changed, 79 insertions, 23 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index fe19ff441..a8b2de958 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -26,20 +26,6 @@ static inline struct msgb *gsm48_msgb_alloc_name(const char *name)
name);
}
-static inline int get_radio_link_timeout(struct gsm48_cell_options *cell_options)
-{
- return (cell_options->radio_link_timeout + 1) << 2;
-}
-
-static inline void set_radio_link_timeout(struct gsm48_cell_options *cell_options, int value)
-{
- if (value < 4)
- value = 4;
- if (value > 64)
- value = 64;
- cell_options->radio_link_timeout = (value >> 2) - 1;
-}
-
/* config options controlling the behaviour of the lower leves */
void gsm0408_allow_everyone(int allow);
void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 5ab7c3fbd..a97405105 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -590,4 +590,7 @@ void bts_depend_clear(struct gsm_bts *bts, int dep);
int bts_depend_check(struct gsm_bts *bts);
int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);
+int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts);
+void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);
+
#endif /* _GSM_DATA_H */
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index d3fd75700..4c71a075e 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -872,6 +872,8 @@ struct gsm_bts {
} data;
} si_common;
bool early_classmark_allowed;
+ /* for testing only: Have an infinitely long radio link timeout */
+ bool infinite_radio_link_timeout;
/* do we use static (user-defined) system information messages? (bitmask) */
uint32_t si_mode_static;
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 2fc39ab4c..9fc289503 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -604,9 +604,11 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " periodic location update %u%s",
bts->si_common.chan_desc.t3212 * 6, VTY_NEWLINE);
- vty_out(vty, " radio-link-timeout %d%s",
- get_radio_link_timeout(&bts->si_common.cell_options),
- VTY_NEWLINE);
+ if (gsm_bts_get_radio_link_timeout(bts) < 0)
+ vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
+ else
+ vty_out(vty, " radio-link-timeout %d%s",
+ gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
vty_out(vty, " channel allocator %s%s",
bts->chan_alloc_reverse ? "descending" : "ascending",
VTY_NEWLINE);
@@ -2299,7 +2301,25 @@ DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
{
struct gsm_bts *bts = vty->index;
- set_radio_link_timeout(&bts->si_common.cell_options, atoi(argv[0]));
+ gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
+ "radio-link-timeout infinite",
+ "Radio link timeout criterion (BTS side)\n"
+ "Infinite Radio link timeout value (use only for BTS RF testing)\n")
+{
+ struct gsm_bts *bts = vty->index;
+
+ if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
+ vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
+ gsm_bts_set_radio_link_timeout(bts, -1);
return CMD_SUCCESS;
}
@@ -4180,6 +4200,7 @@ int bsc_vty_init(struct gsm_network *network)
install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
+ install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
diff --git a/openbsc/src/libbsc/bts_ipaccess_nanobts_omlattr.c b/openbsc/src/libbsc/bts_ipaccess_nanobts_omlattr.c
index 0291129d0..473e1caea 100644
--- a/openbsc/src/libbsc/bts_ipaccess_nanobts_omlattr.c
+++ b/openbsc/src/libbsc/bts_ipaccess_nanobts_omlattr.c
@@ -38,6 +38,7 @@ struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts)
{
struct msgb *msgb;
uint8_t buf[256];
+ int rlt;
msgb = msgb_alloc(1024, "nanobts_attr_bts");
memcpy(buf, "\x55\x5b\x61\x67\x6d\x73", 6);
@@ -46,9 +47,16 @@ struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts)
/* interference avg. period in numbers of SACCH multifr */
msgb_tv_put(msgb, NM_ATT_INTAVE_PARAM, 0x06);
- /* conn fail based on SACCH error rate */
- buf[0] = 0x01;
- buf[1] = get_radio_link_timeout(&bts->si_common.cell_options);
+ rlt = gsm_bts_get_radio_link_timeout(bts);
+ if (rlt == -1) {
+ /* Osmocom extension: Use infinite radio link timeout */
+ buf[0] = 0xFF;
+ buf[1] = 0x00;
+ } else {
+ /* conn fail based on SACCH error rate */
+ buf[0] = 0x01;
+ buf[1] = rlt;
+ }
msgb_tl16v_put(msgb, NM_ATT_CONN_FAIL_CRIT, 2, buf);
memcpy(buf, "\x1e\x24\x24\xa8\x34\x21\xa8", 7);
diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c
index 8830ce144..db7de082d 100644
--- a/openbsc/src/libcommon/gsm_data.c
+++ b/openbsc/src/libcommon/gsm_data.c
@@ -323,8 +323,7 @@ struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_typ
bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */
bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */
bts->si_common.chan_desc.t3212 = 5; /* Use 30 min periodic update interval as sane default */
- set_radio_link_timeout(&bts->si_common.cell_options, 32);
- /* Use RADIO LINK TIMEOUT of 32 seconds */
+ gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */
llist_add_tail(&bts->list, &net->bts_list);
@@ -435,3 +434,40 @@ int bts_depend_check(struct gsm_bts *bts)
}
return 1;
}
+
+/* get the radio link timeout (based on SACCH decode errors, according
+ * to algorithm specified in TS 05.08 section 5.2. A value of -1
+ * indicates we should use an infinitely long timeout, which only works
+ * with OsmoBTS as the BTS implementation */
+int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts)
+{
+ const struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
+
+ if (bts->infinite_radio_link_timeout)
+ return -1;
+ else {
+ /* Encoding as per Table 10.5.21 of TS 04.08 */
+ return (cell_options->radio_link_timeout + 1) << 2;
+ }
+}
+
+/* set the radio link timeout (based on SACCH decode errors, according
+ * to algorithm specified in TS 05.08 Section 5.2. A value of -1
+ * indicates we should use an infinitely long timeout, which only works
+ * with OsmoBTS as the BTS implementation */
+void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value)
+{
+ struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
+
+ if (value < 0)
+ bts->infinite_radio_link_timeout = true;
+ else {
+ bts->infinite_radio_link_timeout = false;
+ /* Encoding as per Table 10.5.21 of TS 04.08 */
+ if (value < 4)
+ value = 4;
+ if (value > 64)
+ value = 64;
+ cell_options->radio_link_timeout = (value >> 2) - 1;
+ }
+}