aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2018-11-07 14:19:32 +0100
committerHarald Welte <laforge@gnumonks.org>2018-12-05 19:40:23 +0000
commit1b96334b26b8abea3e82a1aa5a17925cbbf75f2c (patch)
tree5f4977fb4f48a46d209aa5147d68dbcd5eb3d9d0
parent4af2d188140d61b227f2330e4ccf434d4f9a1185 (diff)
paging: Add VTY options to calculate T3113 timeout dynamically
The idea is to have a base static value which is set like before "timer t3113 [seconds]", but now have a part of this timeout calculated dynamically based on BTS channel configuration and channel load. This patch only implements initial support to calculate based on channel configuration, but doesn't include code to calculate based on channel load. To implement the later part, we probably need to keep track of BTS paging queues per paging group, which we don't do nowadays. Dynamic calculation is enabled by default, and default static base value is decreased accordingly. This way, in a typical setup were the default 10 seconds were used, now the calculated final value is 11 seconds. That's intended because it was observed experimentally in osmo-gsm-tester with a similar channel setup that sometimes paging response can arrive slightly later than 10 seconds. Related: OS#3680 Change-Id: I4fb2969b690151415038631fb6ad059aa6835c7f
-rw-r--r--include/osmocom/bsc/gsm_data.h1
-rw-r--r--include/osmocom/bsc/gsm_timers.h2
-rw-r--r--src/osmo-bsc/bsc_vty.c52
-rw-r--r--src/osmo-bsc/gsm_data.c1
-rw-r--r--src/osmo-bsc/gsm_timers_vty.c2
-rw-r--r--src/osmo-bsc/net_init.c2
-rw-r--r--src/osmo-bsc/paging.c30
7 files changed, 86 insertions, 4 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 0b472a4..e57da55 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1147,6 +1147,7 @@ struct gsm_bts {
/* BTS-specific overrides for timer values from struct gsm_network. */
uint8_t T3122; /* ASSIGMENT REJECT wait indication */
+ bool T3113_dynamic; /* Calculate T3113 timeout dynamically based on BTS channel config and load */
/* Periodic channel load measurements are used to maintain T3122. */
struct load_counter chan_load_samples[7];
diff --git a/include/osmocom/bsc/gsm_timers.h b/include/osmocom/bsc/gsm_timers.h
index 78f04ed..699c461 100644
--- a/include/osmocom/bsc/gsm_timers.h
+++ b/include/osmocom/bsc/gsm_timers.h
@@ -37,7 +37,7 @@ struct T_def *T_def_get_entry(struct T_def *T_defs, int T);
void T_defs_vty_init(struct T_def *T_defs, int cfg_parent_node);
void T_defs_vty_write(struct vty *vty, const char *indent);
-
+struct T_def *parse_T_arg(struct vty *vty, const char *T_str);
struct state_timeout {
int T;
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 983dcb9..8c7d8e1 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -3951,6 +3951,56 @@ DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
return check_amr_config(vty);
}
+#define TNUM_STR "T-number, optionally preceded by 't' or 'T'\n"
+DEFUN(cfg_bts_t3113_dynamic, cfg_bts_t3113_dynamic_cmd,
+ "timer-dynamic TNNNN",
+ "Calculate T3113 dynamically based on channel config and load\n"
+ TNUM_STR)
+{
+ struct T_def *d;
+ struct gsm_bts *bts = vty->index;
+
+ d = parse_T_arg(vty, argv[0]);
+ if (!d)
+ return CMD_WARNING;
+
+ switch (d->T) {
+ case 3113:
+ bts->T3113_dynamic = true;
+ break;
+ default:
+ vty_out(vty, "T%d cannot be set to dynamic%s", d->T, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_no_t3113_dynamic, cfg_bts_no_t3113_dynamic_cmd,
+ "no timer-dynamic TNNNN",
+ NO_STR
+ "Set given timer to non-dynamic and use the default or user provided fixed value\n"
+ TNUM_STR)
+{
+ struct T_def *d;
+ struct gsm_bts *bts = vty->index;
+
+ d = parse_T_arg(vty, argv[0]);
+ if (!d)
+ return CMD_WARNING;
+
+ switch (d->T) {
+ case 3113:
+ bts->T3113_dynamic = false;
+ break;
+ default:
+ vty_out(vty, "T%d already is non-dynamic%s", d->T, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
#define TRX_TEXT "Radio Transceiver\n"
/* per TRX configuration */
@@ -5129,6 +5179,8 @@ int bsc_vty_init(struct gsm_network *network)
install_element(BTS_NODE, &cfg_bts_no_acc_ramping_cmd);
install_element(BTS_NODE, &cfg_bts_acc_ramping_step_interval_cmd);
install_element(BTS_NODE, &cfg_bts_acc_ramping_step_size_cmd);
+ install_element(BTS_NODE, &cfg_bts_t3113_dynamic_cmd);
+ install_element(BTS_NODE, &cfg_bts_no_t3113_dynamic_cmd);
neighbor_ident_vty_init(network, network->neighbor_bss_cells);
/* See also handover commands added on bts level from handover_vty.c */
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index 6d39642..0f76a27 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -849,6 +849,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num)
/* timer overrides */
bts->T3122 = 0; /* not overriden by default */
+ bts->T3113_dynamic = true; /* dynamic by default */
bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
bts->dtxd = false;
diff --git a/src/osmo-bsc/gsm_timers_vty.c b/src/osmo-bsc/gsm_timers_vty.c
index de61e24..e744dfa 100644
--- a/src/osmo-bsc/gsm_timers_vty.c
+++ b/src/osmo-bsc/gsm_timers_vty.c
@@ -32,7 +32,7 @@ static struct T_def *g_vty_T_defs = NULL;
/* Parse an argument like "T1234", "t1234" or "1234" and return the corresponding T_def entry from
* g_vty_T_defs, if any. */
-static struct T_def *parse_T_arg(struct vty *vty, const char *T_str)
+struct T_def *parse_T_arg(struct vty *vty, const char *T_str)
{
int T;
struct T_def *d;
diff --git a/src/osmo-bsc/net_init.c b/src/osmo-bsc/net_init.c
index 1199bdc..5ea564d 100644
--- a/src/osmo-bsc/net_init.c
+++ b/src/osmo-bsc/net_init.c
@@ -37,7 +37,7 @@ static struct T_def gsm_network_T_defs[] = {
{ .T=3109, .default_val=5, .desc="RSL SACCH deactivation" },
{ .T=3111, .default_val=2, .desc="Wait time before RSL RF Channel Release" },
{ .T=993111, .default_val=4, .desc="Wait time after lchan was released in error (should be T3111 + 2s)" },
- { .T=3113, .default_val=10, .desc="Paging"},
+ { .T=3113, .default_val=7, .desc="Paging"},
{ .T=3115, .default_val=10, .desc="(unused)" },
{ .T=3117, .default_val=10, .desc="(unused)" },
{ .T=3119, .default_val=10, .desc="(unused)" },
diff --git a/src/osmo-bsc/paging.c b/src/osmo-bsc/paging.c
index afe3245..246114f 100644
--- a/src/osmo-bsc/paging.c
+++ b/src/osmo-bsc/paging.c
@@ -287,6 +287,32 @@ static void paging_T3113_expired(void *data)
paging_remove_request(&req->bts->paging, req);
}
+#define GSM_FRAME_DURATION_us 4615
+#define GSM51_MFRAME_DURATION_us (51 * GSM_FRAME_DURATION_us) /* 235365 us */
+static unsigned int calculate_timer_3113(struct gsm_bts *bts)
+{
+ unsigned int to_us, to;
+ struct T_def *d = T_def_get_entry(bts->network->T_defs, 3113);
+
+ if (!bts->T3113_dynamic)
+ return d->val;
+
+ /* TODO: take into account load of paging group for req->bsub */
+
+ /* MFRMS defines repeat interval of paging messages for MSs that belong
+ * to same paging group accross multiple 51 frame multiframes.
+ * MAXTRANS defines maximum number of RACH retransmissions.
+ */
+ to_us = GSM51_MFRAME_DURATION_us * (bts->si_common.chan_desc.bs_pa_mfrms + 2) *
+ bts->si_common.rach_control.max_trans;
+
+ /* ceiling in seconds + extra time */
+ to = (to_us + 999999) / 1000000 + d->val;
+ LOGP(DPAG, LOGL_DEBUG, "(bts=%d) Paging request: T3113 expires in %u seconds\n",
+ bts->nr, to);
+ return to;
+}
+
/*! Start paging + paging timer for given subscriber on given BTS
* \param bts BTS on which to page
* \param[in] bsub subscriber we want to page
@@ -298,6 +324,7 @@ static int _paging_request(struct gsm_bts *bts, struct bsc_subscr *bsub, int typ
{
struct gsm_bts_paging_state *bts_entry = &bts->paging;
struct gsm_paging_request *req;
+ unsigned int t3113_timeout_s;
rate_ctr_inc(&bts->bts_ctrs->ctr[BTS_CTR_PAGING_ATTEMPTED]);
@@ -317,7 +344,8 @@ static int _paging_request(struct gsm_bts *bts, struct bsc_subscr *bsub, int typ
req->chan_type = type;
req->msc = msc;
osmo_timer_setup(&req->T3113, paging_T3113_expired, req);
- osmo_timer_schedule(&req->T3113, T_def_get(bts->network->T_defs, 3113, T_S, -1), 0);
+ t3113_timeout_s = calculate_timer_3113(bts);
+ osmo_timer_schedule(&req->T3113, t3113_timeout_s, 0);
llist_add_tail(&req->entry, &bts_entry->pending_requests);
paging_schedule_if_needed(bts_entry);