diff options
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/gprs_ns.h | 22 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_ns.c | 70 |
2 files changed, 79 insertions, 13 deletions
diff --git a/openbsc/include/openbsc/gprs_ns.h b/openbsc/include/openbsc/gprs_ns.h index 60051d13..847e8f9c 100644 --- a/openbsc/include/openbsc/gprs_ns.h +++ b/openbsc/include/openbsc/gprs_ns.h @@ -75,7 +75,6 @@ enum ns_cause { NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14, }; - /* Our Implementation */ #include <netinet/in.h> #include <osmocore/linuxlist.h> @@ -83,6 +82,25 @@ enum ns_cause { #include <osmocore/timer.h> #include <osmocore/select.h> +#define NS_TIMERS_COUNT 7 +#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)" +#define NS_TIMERS_HELP \ + "(un)blocking Timer (Tns-block) timeout\n" \ + "(un)blocking Timer (Tns-block) number of retries\n" \ + "Reset Timer (Tns-reset) timeout\n" \ + "Reset Timer (Tns-reset) number of retries\n" \ + "Test Timer (Tns-test) timeout\n" \ + +enum ns_timeout { + NS_TOUT_TNS_BLOCK, + NS_TOUT_TNS_BLOCK_RETRIES, + NS_TOUT_TNS_RESET, + NS_TOUT_TNS_RESET_RETRIES, + NS_TOUT_TNS_TEST, + NS_TOUT_TNS_ALIVE, + NS_TOUT_TNS_ALIVE_RETRIES, +}; + #define NSE_S_BLOCKED 0x0001 #define NSE_S_ALIVE 0x0002 @@ -107,6 +125,8 @@ struct gprs_ns_inst { /* linked lists of all NSVC in this instance */ struct llist_head gprs_nsvcs; + uint16_t timeout[NS_TIMERS_COUNT]; + /* which link-layer are we based on? */ enum gprs_ns_ll ll; diff --git a/openbsc/src/gprs/gprs_ns.c b/openbsc/src/gprs/gprs_ns.c index e0ee962d..1b9d7c6d 100644 --- a/openbsc/src/gprs/gprs_ns.c +++ b/openbsc/src/gprs/gprs_ns.c @@ -63,6 +63,19 @@ #define NS_ALLOC_SIZE 1024 +/* FIXME: this should go to some common file as it is copied + * in vty_interface.c of the BSC */ +static const struct value_string gprs_ns_timer_strs[] = { + { 0, "tns-block" }, + { 1, "tns-block-retries" }, + { 2, "tns-reset" }, + { 3, "tns-reset-retries" }, + { 4, "tns-test" }, + { 5, "tns-alive" }, + { 6, "tns-alive-retries" }, + { 0, NULL } +}; + static const struct tlv_definition ns_att_tlvdef = { .def = { [NS_IE_CAUSE] = { TLV_TYPE_TvLV, 0 }, @@ -323,12 +336,10 @@ int gprs_ns_tx_alive_ack(struct gprs_nsvc *nsvc) return gprs_ns_tx_simple(nsvc, NS_PDUT_ALIVE_ACK); } -#define NS_ALIVE_RETRIES 10 /* after 3 failed retransmit we declare BTS as dead */ - -static const uint8_t timer_mode_tout[_NSVC_TIMER_NR] = { - [NSVC_TIMER_TNS_RESET] = 60, - [NSVC_TIMER_TNS_ALIVE] = 3, - [NSVC_TIMER_TNS_TEST] = 30, +static const enum ns_timeout timer_mode_tout[_NSVC_TIMER_NR] = { + [NSVC_TIMER_TNS_RESET] = NS_TOUT_TNS_RESET, + [NSVC_TIMER_TNS_ALIVE] = NS_TOUT_TNS_ALIVE, + [NSVC_TIMER_TNS_TEST] = NS_TOUT_TNS_TEST, }; static const struct value_string timer_mode_strs[] = { @@ -340,36 +351,42 @@ static const struct value_string timer_mode_strs[] = { static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode) { + enum ns_timeout tout = timer_mode_tout[mode]; + unsigned int seconds = nsvc->nsi->timeout[tout]; + DEBUGP(DNS, "NSEI=%u Starting timer in mode %s (%u seconds)\n", nsvc->nsei, get_value_string(timer_mode_strs, mode), - timer_mode_tout[mode]); + seconds); if (bsc_timer_pending(&nsvc->timer)) bsc_del_timer(&nsvc->timer); nsvc->timer_mode = mode; - bsc_schedule_timer(&nsvc->timer, timer_mode_tout[mode], 0); + bsc_schedule_timer(&nsvc->timer, seconds, 0); } static void gprs_ns_timer_cb(void *data) { struct gprs_nsvc *nsvc = data; + enum ns_timeout tout = timer_mode_tout[nsvc->timer_mode]; + unsigned int seconds = nsvc->nsi->timeout[tout]; DEBUGP(DNS, "NSEI=%u Timer expired in mode %s (%u seconds)\n", nsvc->nsei, get_value_string(timer_mode_strs, nsvc->timer_mode), - timer_mode_tout[nsvc->timer_mode]); + seconds); switch (nsvc->timer_mode) { case NSVC_TIMER_TNS_ALIVE: /* Tns-alive case: we expired without response ! */ nsvc->alive_retries++; - if (nsvc->alive_retries > NS_ALIVE_RETRIES) { + if (nsvc->alive_retries > + nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]) { /* mark as dead and blocked */ nsvc->state = NSE_S_BLOCKED; LOGP(DNS, LOGL_NOTICE, "NSEI=%u Tns-alive expired more then " "%u times, blocking NS-VC\n", nsvc->nsei, - NS_ALIVE_RETRIES); + nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]); ns_dispatch_signal(nsvc, S_NS_ALIVE_EXP, 0); ns_dispatch_signal(nsvc, S_NS_BLOCK, NS_CAUSE_NSVC_BLOCKED); return; @@ -710,6 +727,13 @@ struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb) nsi->cb = cb; INIT_LLIST_HEAD(&nsi->gprs_nsvcs); + nsi->timeout[NS_TOUT_TNS_BLOCK] = 3; + nsi->timeout[NS_TOUT_TNS_BLOCK_RETRIES] = 3; + nsi->timeout[NS_TOUT_TNS_RESET] = 3; + nsi->timeout[NS_TOUT_TNS_RESET_RETRIES] = 3; + nsi->timeout[NS_TOUT_TNS_TEST] = 30; + nsi->timeout[NS_TOUT_TNS_ALIVE] = 3; + nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES] = 10; return nsi; } @@ -866,6 +890,7 @@ static struct cmd_node ns_node = { static int config_write_ns(struct vty *vty) { struct gprs_nsvc *nsvc; + unsigned int i; vty_out(vty, "ns%s", VTY_NEWLINE); @@ -886,9 +911,13 @@ static int config_write_ns(struct vty *vty) nsvc->nsei, ntohs(nsvc->ip.bts_addr.sin_port), VTY_NEWLINE); } - vty_out(vty, "%s", VTY_NEWLINE); } + for (i = 0; i < ARRAY_SIZE(vty_nsi->timeout); i++) + vty_out(vty, " timer %s %u%s", + get_value_string(gprs_ns_timer_strs, i), + vty_nsi->timeout[i], VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1034,6 +1063,22 @@ DEFUN(cfg_no_nse, cfg_no_nse_cmd, return CMD_SUCCESS; } +DEFUN(cfg_ns_timer, cfg_ns_timer_cmd, + "timer " NS_TIMERS " <0-65535>", + "Network Service Timer\n" + NS_TIMERS_HELP "Timer Value\n") +{ + int idx = get_string_value(gprs_ns_timer_strs, argv[0]); + int val = atoi(argv[1]); + + if (idx < 0 || idx >= ARRAY_SIZE(vty_nsi->timeout)) + return CMD_WARNING; + + vty_nsi->timeout[idx] = val; + + return CMD_SUCCESS; +} + int gprs_ns_vty_init(struct gprs_ns_inst *nsi) { vty_nsi = nsi; @@ -1048,6 +1093,7 @@ int gprs_ns_vty_init(struct gprs_ns_inst *nsi) install_element(NS_NODE, &cfg_nse_remoteport_cmd); install_element(NS_NODE, &cfg_nse_remoterole_cmd); install_element(NS_NODE, &cfg_no_nse_cmd); + install_element(NS_NODE, &cfg_ns_timer_cmd); return 0; } |