diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bsc/bsc_vty.c | 52 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_data.c | 1 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_timers_vty.c | 2 | ||||
-rw-r--r-- | src/osmo-bsc/net_init.c | 2 | ||||
-rw-r--r-- | src/osmo-bsc/paging.c | 30 |
5 files changed, 84 insertions, 3 deletions
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c index 983dcb9b3..8c7d8e19d 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 6d39642e2..0f76a2746 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 de61e2453..e744dfac5 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 1199bdc82..5ea564d70 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 afe32453e..246114f74 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); |