<p>Neels Hofmeyr has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13795">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">use libosmocore osmo_tdef<br><br>Move the T_defs API to libosmocore as osmo_tdefs: remove the local T_defs API<br>and use libosmocore's osmo_tdef* API instead.<br><br>The root reason is moving the mgw_endpoint_fsm to libosmo-mgcp-client to be<br>able to use it in osmo-msc for inter-MSC handover.<br><br>When adding osmo_tdef, the new concept of timer groups was added to the API. It<br>would make sense to apply group names here as well, but do not modify the VTY<br>configuration for timers. The future might bring separate groups (or not).<br><br>Depends: Ibd6b1ed7f1bd6e1f2e0fde53352055a4468f23e5 (libosmocore)<br>Change-Id: I66674a5d8403d820038762888c846bae10ceac58<br>---<br>M include/osmocom/bsc/Makefile.am<br>M include/osmocom/bsc/gsm_data.h<br>D include/osmocom/bsc/gsm_timers.h<br>M include/osmocom/bsc/mgw_endpoint_fsm.h<br>M src/ipaccess/Makefile.am<br>M src/osmo-bsc/Makefile.am<br>M src/osmo-bsc/abis_om2000.c<br>M src/osmo-bsc/abis_rsl.c<br>M src/osmo-bsc/assignment_fsm.c<br>M src/osmo-bsc/bsc_subscr_conn_fsm.c<br>M src/osmo-bsc/bsc_vty.c<br>M src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c<br>M src/osmo-bsc/bts_siemens_bs11.c<br>M src/osmo-bsc/gsm_data.c<br>D src/osmo-bsc/gsm_timers.c<br>D src/osmo-bsc/gsm_timers_vty.c<br>M src/osmo-bsc/handover_fsm.c<br>M src/osmo-bsc/lchan_fsm.c<br>M src/osmo-bsc/lchan_rtp_fsm.c<br>M src/osmo-bsc/mgw_endpoint_fsm.c<br>M src/osmo-bsc/net_init.c<br>M src/osmo-bsc/paging.c<br>M src/utils/Makefile.am<br>M tests/abis/Makefile.am<br>M tests/bsc/Makefile.am<br>M tests/gsm0408/Makefile.am<br>M tests/handover/Makefile.am<br>M tests/nanobts_omlattr/Makefile.am<br>M tests/nanobts_omlattr/nanobts_omlattr_test.c<br>29 files changed, 94 insertions(+), 468 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/95/13795/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am</span><br><span>index 044fdc9..21e53d7 100644</span><br><span>--- a/include/osmocom/bsc/Makefile.am</span><br><span>+++ b/include/osmocom/bsc/Makefile.am</span><br><span>@@ -20,7 +20,6 @@</span><br><span>   gsm_04_08_rr.h \</span><br><span>     gsm_04_80.h \</span><br><span>        gsm_data.h \</span><br><span style="color: hsl(0, 100%, 40%);">-    gsm_timers.h \</span><br><span>       handover.h \</span><br><span>         handover_cfg.h \</span><br><span>     handover_decision.h \</span><br><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index dc133e1..7b813a6 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -17,6 +17,7 @@</span><br><span> #include <osmocom/gsm/gsm0808.h></span><br><span> #include <osmocom/gsm/gsm48.h></span><br><span> #include <osmocom/core/fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/tdef.h></span><br><span> </span><br><span> #include <osmocom/crypt/auth.h></span><br><span> </span><br><span>@@ -31,7 +32,6 @@</span><br><span> #include <osmocom/bsc/meas_rep.h></span><br><span> #include <osmocom/bsc/bsc_msg_filter.h></span><br><span> #include <osmocom/bsc/acc_ramp.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span> </span><br><span> #define GSM_T3122_DEFAULT 10</span><br><span>@@ -1495,7 +1495,7 @@</span><br><span>      struct llist_head bts_rejected;</span><br><span> </span><br><span>  /* shall reference gsm_network_T[] */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct T_def *T_defs;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_tdef *T_defs;</span><br><span> </span><br><span>        enum gsm_chan_t ctype_by_chreq[_NUM_CHREQ_T];</span><br><span> </span><br><span>diff --git a/include/osmocom/bsc/gsm_timers.h b/include/osmocom/bsc/gsm_timers.h</span><br><span>deleted file mode 100644</span><br><span>index 699c461..0000000</span><br><span>--- a/include/osmocom/bsc/gsm_timers.h</span><br><span>+++ /dev/null</span><br><span>@@ -1,56 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* API to define Tnnn timers globally, configure in VTY and use for FSM state changes. */</span><br><span style="color: hsl(0, 100%, 40%);">-#pragma once</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct osmo_fsm_inst;</span><br><span style="color: hsl(0, 100%, 40%);">-struct vty;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum T_unit {</span><br><span style="color: hsl(0, 100%, 40%);">-    T_S = 0,        /*< most T are in seconds, keep 0 as default. */</span><br><span style="color: hsl(0, 100%, 40%);">-     T_MS,           /*< milliseconds */</span><br><span style="color: hsl(0, 100%, 40%);">-  T_M,            /*< minutes */</span><br><span style="color: hsl(0, 100%, 40%);">-       T_CUSTOM,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-extern const struct value_string T_unit_names[];</span><br><span style="color: hsl(0, 100%, 40%);">-static inline const char *T_unit_name(enum T_unit val)</span><br><span style="color: hsl(0, 100%, 40%);">-{ return get_value_string(T_unit_names, val); }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Define a GSM timer of the form Tnnn, with unit, default value and doc string. */</span><br><span style="color: hsl(0, 100%, 40%);">-struct T_def {</span><br><span style="color: hsl(0, 100%, 40%);">-       const int T; /*< T1234 number */</span><br><span style="color: hsl(0, 100%, 40%);">-     const int default_val; /*< timeout duration (according to unit), default value. */</span><br><span style="color: hsl(0, 100%, 40%);">-   const enum T_unit unit;</span><br><span style="color: hsl(0, 100%, 40%);">- const char *desc;</span><br><span style="color: hsl(0, 100%, 40%);">-       int val; /*< currently active value, e.g. set by user config. */</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Iterate an array of struct T_def, the last item should be fully zero, i.e. "{}" */</span><br><span style="color: hsl(0, 100%, 40%);">-#define for_each_T_def(d, T_defs) \</span><br><span style="color: hsl(0, 100%, 40%);">- for (d = T_defs; d && (d->T || d->default_val || d->desc); d++)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int T_def_get(const struct T_def *T_defs, int T, enum T_unit as_unit, int val_if_not_present);</span><br><span style="color: hsl(0, 100%, 40%);">-void T_defs_reset(struct T_def *T_defs);</span><br><span style="color: hsl(0, 100%, 40%);">-struct T_def *T_def_get_entry(struct T_def *T_defs, int T);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void T_defs_vty_init(struct T_def *T_defs, int cfg_parent_node);</span><br><span style="color: hsl(0, 100%, 40%);">-void T_defs_vty_write(struct vty *vty, const char *indent);</span><br><span style="color: hsl(0, 100%, 40%);">-struct T_def *parse_T_arg(struct vty *vty, const char *T_str);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct state_timeout {</span><br><span style="color: hsl(0, 100%, 40%);">-        int T;</span><br><span style="color: hsl(0, 100%, 40%);">-  bool keep_timer;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const struct state_timeout *get_state_timeout(uint32_t state,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       const struct state_timeout *timeouts_array);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define fsm_inst_state_chg_T(fi, state, timeouts_array, T_defs, default_timeout) \</span><br><span style="color: hsl(0, 100%, 40%);">-    _fsm_inst_state_chg_T(fi, state, timeouts_array, T_defs, default_timeout, \</span><br><span style="color: hsl(0, 100%, 40%);">-                           __FILE__, __LINE__)</span><br><span style="color: hsl(0, 100%, 40%);">-int _fsm_inst_state_chg_T(struct osmo_fsm_inst *fi, uint32_t state,</span><br><span style="color: hsl(0, 100%, 40%);">-                      const struct state_timeout *timeouts_array,</span><br><span style="color: hsl(0, 100%, 40%);">-                     const struct T_def *T_defs, int default_timeout,</span><br><span style="color: hsl(0, 100%, 40%);">-                        const char *file, int line);</span><br><span>diff --git a/include/osmocom/bsc/mgw_endpoint_fsm.h b/include/osmocom/bsc/mgw_endpoint_fsm.h</span><br><span>index e264a3c..f86a7cd 100644</span><br><span>--- a/include/osmocom/bsc/mgw_endpoint_fsm.h</span><br><span>+++ b/include/osmocom/bsc/mgw_endpoint_fsm.h</span><br><span>@@ -24,9 +24,9 @@</span><br><span> </span><br><span> struct mgw_endpoint;</span><br><span> struct mgwep_ci;</span><br><span style="color: hsl(0, 100%, 40%);">-struct T_def;</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_tdef;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void mgw_endpoint_fsm_init(struct T_def *T_defs);</span><br><span style="color: hsl(120, 100%, 40%);">+void mgw_endpoint_fsm_init(struct osmo_tdef *T_defs);</span><br><span> </span><br><span> struct mgw_endpoint *mgw_endpoint_alloc(struct osmo_fsm_inst *parent, uint32_t parent_term_event,</span><br><span>                                         struct mgcp_client *mgcp_client,</span><br><span>diff --git a/src/ipaccess/Makefile.am b/src/ipaccess/Makefile.am</span><br><span>index 3578a40..145ea39 100644</span><br><span>--- a/src/ipaccess/Makefile.am</span><br><span>+++ b/src/ipaccess/Makefile.am</span><br><span>@@ -50,7 +50,6 @@</span><br><span>    $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/net_init.o \</span><br><span>    $(OSMO_LIBS) \</span><br><span>       $(NULL)</span><br><span>@@ -62,6 +61,5 @@</span><br><span>  $(NULL)</span><br><span> </span><br><span> ipaccess_proxy_LDADD = \</span><br><span style="color: hsl(0, 100%, 40%);">- $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(OSMO_LIBS) \</span><br><span>       $(NULL)</span><br><span>diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am</span><br><span>index 364228d..11803da 100644</span><br><span>--- a/src/osmo-bsc/Makefile.am</span><br><span>+++ b/src/osmo-bsc/Makefile.am</span><br><span>@@ -57,8 +57,6 @@</span><br><span>     gsm_04_08_rr.c \</span><br><span>     gsm_04_80_utils.c \</span><br><span>  gsm_data.c \</span><br><span style="color: hsl(0, 100%, 40%);">-    gsm_timers.c \</span><br><span style="color: hsl(0, 100%, 40%);">-  gsm_timers_vty.c \</span><br><span>   handover_cfg.c \</span><br><span>     handover_decision.c \</span><br><span>        handover_decision_2.c \</span><br><span>diff --git a/src/osmo-bsc/abis_om2000.c b/src/osmo-bsc/abis_om2000.c</span><br><span>index 9715dfc..fda273d 100644</span><br><span>--- a/src/osmo-bsc/abis_om2000.c</span><br><span>+++ b/src/osmo-bsc/abis_om2000.c</span><br><span>@@ -42,7 +42,6 @@</span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span> #include <osmocom/bsc/abis_om2000.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/abis/e1_input.h></span><br><span> </span><br><span>@@ -1381,7 +1380,7 @@</span><br><span>           break;</span><br><span>       case GSM_PCHAN_CCCH_SDCCH4:</span><br><span>          msgb_tv_put(msg, OM2K_DEI_T3105,</span><br><span style="color: hsl(0, 100%, 40%);">-                            T_def_get(ts->trx->bts->network->T_defs, 3105, T_MS, -1) / 10);</span><br><span style="color: hsl(120, 100%, 40%);">+                           osmo_tdef_get(ts->trx->bts->network->T_defs, 3105, OSMO_TDEF_MS, -1) / 10);</span><br><span>          msgb_tv_put(msg, OM2K_DEI_NY1, 35);</span><br><span>          msgb_tv_put(msg, OM2K_DEI_BA_PA_MFRMS, 0x06);</span><br><span>                msgb_tv_put(msg, OM2K_DEI_CBCH_INDICATOR, 0);</span><br><span>@@ -1396,7 +1395,7 @@</span><br><span>                break;</span><br><span>       case GSM_PCHAN_SDCCH8_SACCH8C:</span><br><span>               msgb_tv_put(msg, OM2K_DEI_T3105,</span><br><span style="color: hsl(0, 100%, 40%);">-                            T_def_get(ts->trx->bts->network->T_defs, 3105, T_MS, -1) / 10);</span><br><span style="color: hsl(120, 100%, 40%);">+                           osmo_tdef_get(ts->trx->bts->network->T_defs, 3105, OSMO_TDEF_MS, -1) / 10);</span><br><span>          msgb_tv_put(msg, OM2K_DEI_NY1, 35);</span><br><span>          msgb_tv_put(msg, OM2K_DEI_CBCH_INDICATOR, 0);</span><br><span>                msgb_tv_put(msg, OM2K_DEI_TSC, gsm_ts_tsc(ts));</span><br><span>@@ -1407,7 +1406,7 @@</span><br><span>              break;</span><br><span>       default:</span><br><span>             msgb_tv_put(msg, OM2K_DEI_T3105,</span><br><span style="color: hsl(0, 100%, 40%);">-                            T_def_get(ts->trx->bts->network->T_defs, 3105, T_MS, -1) / 10);</span><br><span style="color: hsl(120, 100%, 40%);">+                           osmo_tdef_get(ts->trx->bts->network->T_defs, 3105, OSMO_TDEF_MS, -1) / 10);</span><br><span>          msgb_tv_put(msg, OM2K_DEI_NY1, 35);</span><br><span>          msgb_tv_put(msg, OM2K_DEI_TSC, gsm_ts_tsc(ts));</span><br><span>              /* Disable RF RESOURCE INDICATION on idle channels */</span><br><span>diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c</span><br><span>index fd6dbdb..0117435 100644</span><br><span>--- a/src/osmo-bsc/abis_rsl.c</span><br><span>+++ b/src/osmo-bsc/abis_rsl.c</span><br><span>@@ -45,7 +45,7 @@</span><br><span> #include <osmocom/bsc/pcu_if.h></span><br><span> #include <osmocom/bsc/gsm_08_08.h></span><br><span> #include <osmocom/netif/rtp.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/tdef.h></span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/lchan_select.h></span><br><span>@@ -1291,7 +1291,7 @@</span><br><span>   uint8_t wait_ind;</span><br><span>    wait_ind = bts->T3122;</span><br><span>    if (!wait_ind)</span><br><span style="color: hsl(0, 100%, 40%);">-          wait_ind = T_def_get(bts->network->T_defs, 3122, T_S, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+              wait_ind = osmo_tdef_get(bts->network->T_defs, 3122, OSMO_TDEF_S, -1);</span><br><span>         if (!wait_ind)</span><br><span>               wait_ind = GSM_T3122_DEFAULT;</span><br><span>        /* The BTS will gather multiple CHAN RQD and reject up to 4 MS at the same time. */</span><br><span>diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c</span><br><span>index 9c0c400..520498f 100644</span><br><span>--- a/src/osmo-bsc/assignment_fsm.c</span><br><span>+++ b/src/osmo-bsc/assignment_fsm.c</span><br><span>@@ -20,13 +20,13 @@</span><br><span>  *</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/tdef.h></span><br><span> #include <osmocom/gsm/gsm0808.h></span><br><span> </span><br><span> #include <osmocom/mgcp_client/mgcp_client_fsm.h></span><br><span> </span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> #include <osmocom/bsc/mgw_endpoint_fsm.h></span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span>@@ -48,7 +48,7 @@</span><br><span>   return fi->priv;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static const struct state_timeout assignment_fsm_timeouts[32] = {</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct osmo_tdef_state_timeout assignment_fsm_timeouts[32] = {</span><br><span>   [ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE] = { .T=10 },</span><br><span>       [ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE] = { .keep_timer=true },</span><br><span>         [ASSIGNMENT_ST_WAIT_LCHAN_ESTABLISHED] = { .keep_timer=true },</span><br><span>@@ -59,10 +59,10 @@</span><br><span>  * The actual timeout value is in turn obtained from network->T_defs.</span><br><span>  * Assumes local variable fi exists. */</span><br><span> #define assignment_fsm_state_chg(state) \</span><br><span style="color: hsl(0, 100%, 40%);">-        fsm_inst_state_chg_T(fi, state, \</span><br><span style="color: hsl(0, 100%, 40%);">-                            assignment_fsm_timeouts, \</span><br><span style="color: hsl(0, 100%, 40%);">-                      ((struct gsm_subscriber_connection*)(fi->priv))->network->T_defs, \</span><br><span style="color: hsl(0, 100%, 40%);">-                            5)</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_tdef_fsm_inst_state_chg(fi, state, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                  assignment_fsm_timeouts, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                    ((struct gsm_subscriber_connection*)(fi->priv))->network->T_defs, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                  5)</span><br><span> </span><br><span> /* Log failure and transition to ASSIGNMENT_ST_FAILURE, which triggers the appropriate actions. */</span><br><span> #define assignment_fail(cause, fmt, args...) do { \</span><br><span>diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>index 1cc0c78..4466404 100644</span><br><span>--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>@@ -37,7 +37,7 @@</span><br><span> #include <osmocom/bsc/penalty_timers.h></span><br><span> #include <osmocom/bsc/bsc_rll.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/tdef.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span> #include <osmocom/bsc/mgw_endpoint_fsm.h></span><br><span> #include <osmocom/bsc/assignment_fsm.h></span><br><span>@@ -85,7 +85,7 @@</span><br><span>        {}</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct state_timeout conn_fsm_timeouts[32] = {</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_tdef_state_timeout conn_fsm_timeouts[32] = {</span><br><span>         [ST_WAIT_CC] = { .T = 993210 },</span><br><span>      [ST_CLEARING] = { .T = 999 },</span><br><span> };</span><br><span>@@ -94,10 +94,10 @@</span><br><span>  * The actual timeout value is in turn obtained from network->T_defs.</span><br><span>  * Assumes local variable 'conn' exists. */</span><br><span> #define conn_fsm_state_chg(state) \</span><br><span style="color: hsl(0, 100%, 40%);">-     fsm_inst_state_chg_T(conn->fi, state, \</span><br><span style="color: hsl(0, 100%, 40%);">-                           conn_fsm_timeouts, \</span><br><span style="color: hsl(0, 100%, 40%);">-                            conn->network->T_defs, \</span><br><span style="color: hsl(0, 100%, 40%);">-                          -1)</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_tdef_fsm_inst_state_chg(conn->fi, state, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                 conn_fsm_timeouts, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                  conn->network->T_defs, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                -1)</span><br><span> </span><br><span> /* forward MT DTAP from BSSAP side to RSL side */</span><br><span> static inline void submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg)</span><br><span>diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c</span><br><span>index 767d565..3a6ddd4 100644</span><br><span>--- a/src/osmo-bsc/bsc_vty.c</span><br><span>+++ b/src/osmo-bsc/bsc_vty.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <osmocom/vty/stats.h></span><br><span> #include <osmocom/vty/telnet_interface.h></span><br><span> #include <osmocom/vty/misc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/vty/tdef_vty.h></span><br><span> #include <osmocom/gsm/protocol/gsm_04_08.h></span><br><span> #include <osmocom/gsm/gsm0502.h></span><br><span> #include <osmocom/ctrl/control_if.h></span><br><span>@@ -66,11 +67,9 @@</span><br><span> #include <osmocom/bsc/meas_feed.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span> #include <osmocom/bsc/handover.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> #include <osmocom/bsc/lchan_select.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/mgw_endpoint_fsm.h></span><br><span> </span><br><span> #include <inttypes.h></span><br><span>@@ -1046,7 +1045,7 @@</span><br><span> </span><br><span>    ho_vty_write_net(vty, gsmnet);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      T_defs_vty_write(vty, " ");</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_tdef_vty_write(vty, gsmnet->T_defs, " ");</span><br><span> </span><br><span>      if (!gsmnet->dyn_ts_allow_tch_f)</span><br><span>          vty_out(vty, " dyn_ts_allow_tch_f 0%s", VTY_NEWLINE);</span><br><span>@@ -1060,7 +1059,7 @@</span><br><span>                              gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* writing T3212 from the common T_defs_vty_write() instead. */</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_tdef_vty_write(vty, gsmnet->T_defs, " timer ");</span><br><span> </span><br><span>        {</span><br><span>            uint16_t meas_port;</span><br><span>@@ -4005,10 +4004,11 @@</span><br><span>        "Calculate T3113 dynamically based on channel config and load\n"</span><br><span>   TNUM_STR)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct T_def *d;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_tdef *d;</span><br><span>         struct gsm_bts *bts = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm_network *gsmnet = gsmnet_from_vty(vty);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  d = parse_T_arg(vty, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+        d = osmo_tdef_vty_parse_T_arg(vty, gsmnet->T_defs, argv[0]);</span><br><span>      if (!d)</span><br><span>              return CMD_WARNING;</span><br><span> </span><br><span>@@ -4030,10 +4030,11 @@</span><br><span>    "Set given timer to non-dynamic and use the default or user provided fixed value\n"</span><br><span>        TNUM_STR)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct T_def *d;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_tdef *d;</span><br><span>         struct gsm_bts *bts = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm_network *gsmnet = gsmnet_from_vty(vty);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  d = parse_T_arg(vty, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+        d = osmo_tdef_vty_parse_T_arg(vty, gsmnet->T_defs, argv[0]);</span><br><span>      if (!d)</span><br><span>              return CMD_WARNING;</span><br><span> </span><br><span>@@ -5042,11 +5043,11 @@</span><br><span>       "Periodic Location Updating Interval in Minutes\n")</span><br><span> {</span><br><span>        struct gsm_network *net = vty->index;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct T_def *d = T_def_get_entry(net->T_defs, 3212);</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_tdef *d = osmo_tdef_get_entry(net->T_defs, 3212);</span><br><span> </span><br><span>         OSMO_ASSERT(d);</span><br><span>      d->val = atoi(argv[0]) / 6;</span><br><span style="color: hsl(0, 100%, 40%);">-  vty_out(vty, "T%d = %u %s (%s)%s", d->T, d->val, "* 6min", d->desc, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+        vty_out(vty, "T%d = %lu %s (%s)%s", d->T, d->val, "* 6min", d->desc, VTY_NEWLINE);</span><br><span>      return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -5058,11 +5059,11 @@</span><br><span>       "Periodic Location Updating Interval\n")</span><br><span> {</span><br><span>      struct gsm_network *net = vty->index;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct T_def *d = T_def_get_entry(net->T_defs, 3212);</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_tdef *d = osmo_tdef_get_entry(net->T_defs, 3212);</span><br><span> </span><br><span>         OSMO_ASSERT(d);</span><br><span>      d->val = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-  vty_out(vty, "T%d = %u %s (%s)%s", d->T, d->val, "* 6min", d->desc, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+        vty_out(vty, "T%d = %lu %s (%s)%s", d->T, d->val, "* 6min", d->desc, VTY_NEWLINE);</span><br><span>      return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -5092,6 +5093,28 @@</span><br><span>        return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(show_timer, show_timer_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "show timer " OSMO_TDEF_VTY_ARG_T_OPTIONAL,</span><br><span style="color: hsl(120, 100%, 40%);">+      SHOW_STR "Show timers\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_TDEF_VTY_DOC_T)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_network *net = gsmnet_from_vty(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *T_arg = argc > 0 ? argv[0] : NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     return osmo_tdef_vty_show_cmd(vty, net->T_defs, T_arg, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_net_timer, cfg_net_timer_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "timer " OSMO_TDEF_VTY_ARG_SET_OPTIONAL,</span><br><span style="color: hsl(120, 100%, 40%);">+      "Configure or show timers\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_TDEF_VTY_DOC_SET)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_network *net = gsmnet_from_vty(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* If any arguments are missing, redirect to 'show' */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (argc < 2)</span><br><span style="color: hsl(120, 100%, 40%);">+              return show_timer(self, vty, argc, argv);</span><br><span style="color: hsl(120, 100%, 40%);">+     return osmo_tdef_vty_set_cmd(vty, net->T_defs, argv);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> extern int bsc_vty_init_extra(void);</span><br><span> </span><br><span> int bsc_vty_init(struct gsm_network *network)</span><br><span>@@ -5136,6 +5159,7 @@</span><br><span>   install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);</span><br><span>   install_element(GSMNET_NODE, &cfg_net_meas_feed_dest_cmd);</span><br><span>       install_element(GSMNET_NODE, &cfg_net_meas_feed_scenario_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+    install_element(GSMNET_NODE, &cfg_net_timer_cmd);</span><br><span> </span><br><span>    install_element_ve(&bsc_show_net_cmd);</span><br><span>   install_element_ve(&show_bts_cmd);</span><br><span>@@ -5146,6 +5170,7 @@</span><br><span>       install_element_ve(&show_lchan_cmd);</span><br><span>     install_element_ve(&show_lchan_summary_cmd);</span><br><span>     install_element_ve(&show_lchan_summary_all_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+  install_element_ve(&show_timer_cmd);</span><br><span> </span><br><span>         install_element_ve(&show_subscr_conn_cmd);</span><br><span> </span><br><span>@@ -5159,8 +5184,6 @@</span><br><span>   logging_vty_add_cmds(NULL);</span><br><span>  osmo_talloc_vty_add_cmds();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- T_defs_vty_init(network->T_defs, GSMNET_NODE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    install_element(GSMNET_NODE, &cfg_net_neci_cmd);</span><br><span>         install_element(GSMNET_NODE, &cfg_net_dtx_cmd);</span><br><span>  install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);</span><br><span>diff --git a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c</span><br><span>index be40410..8a370da 100644</span><br><span>--- a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c</span><br><span>+++ b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c</span><br><span>@@ -23,7 +23,6 @@</span><br><span> #include <osmocom/core/msgb.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> </span><br><span> </span><br><span> struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts)</span><br><span>@@ -82,7 +81,7 @@</span><br><span>         msgb_tv_fixed_put(msgb, NM_ATT_LDAVG_SLOTS, 2, buf);</span><br><span> </span><br><span>     /* 10 milliseconds */</span><br><span style="color: hsl(0, 100%, 40%);">-   msgb_tv_put(msgb, NM_ATT_BTS_AIR_TIMER, T_def_get(bts->network->T_defs, 3105, T_MS, -1));</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_tv_put(msgb, NM_ATT_BTS_AIR_TIMER, osmo_tdef_get(bts->network->T_defs, 3105, OSMO_TDEF_MS, -1));</span><br><span> </span><br><span>      /* 10 retransmissions of physical config */</span><br><span>  msgb_tv_put(msgb, NM_ATT_NY1, 10);</span><br><span>diff --git a/src/osmo-bsc/bts_siemens_bs11.c b/src/osmo-bsc/bts_siemens_bs11.c</span><br><span>index 2cb676c..b1688f3 100644</span><br><span>--- a/src/osmo-bsc/bts_siemens_bs11.c</span><br><span>+++ b/src/osmo-bsc/bts_siemens_bs11.c</span><br><span>@@ -20,6 +20,8 @@</span><br><span>  */</span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/tdef.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/gsm/tlv.h></span><br><span> </span><br><span> #include <osmocom/bsc/debug.h></span><br><span>@@ -27,7 +29,6 @@</span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span> #include <osmocom/abis/e1_input.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> </span><br><span> static int bts_model_bs11_start(struct gsm_network *net);</span><br><span>@@ -360,7 +361,7 @@</span><br><span>   uint8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;</span><br><span> </span><br><span>       /* T3105 attribute in units of 10ms */</span><br><span style="color: hsl(0, 100%, 40%);">-  bs11_attr_bts[2] = T_def_get(bts->network->T_defs, 3105, T_MS, -1) / 10;</span><br><span style="color: hsl(120, 100%, 40%);">+        bs11_attr_bts[2] = osmo_tdef_get(bts->network->T_defs, 3105, OSMO_TDEF_MS, -1) / 10;</span><br><span> </span><br><span>       /* patch ARFCN into BTS Attributes */</span><br><span>        bs11_attr_bts[69] &= 0xf0;</span><br><span>diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c</span><br><span>index 45c433c..88690a7 100644</span><br><span>--- a/src/osmo-bsc/gsm_data.c</span><br><span>+++ b/src/osmo-bsc/gsm_data.c</span><br><span>@@ -40,7 +40,6 @@</span><br><span> #include <osmocom/bsc/osmo_bsc_lcls.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span> #include <osmocom/bsc/handover_cfg.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> </span><br><span>@@ -872,7 +871,7 @@</span><br><span>   bts->si_common.chan_desc.att = 1; /* attachment required */</span><br><span>       bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */</span><br><span>     bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->si_common.chan_desc.t3212 = T_def_get(net->T_defs, 3212, T_CUSTOM, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->si_common.chan_desc.t3212 = osmo_tdef_get(net->T_defs, 3212, OSMO_TDEF_CUSTOM, -1);</span><br><span>       gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */</span><br><span> </span><br><span>      INIT_LLIST_HEAD(&bts->abis_queue);</span><br><span>diff --git a/src/osmo-bsc/gsm_timers.c b/src/osmo-bsc/gsm_timers.c</span><br><span>deleted file mode 100644</span><br><span>index fc3ec24..0000000</span><br><span>--- a/src/osmo-bsc/gsm_timers.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,207 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Implementation to define Tnnn timers globally and use for FSM state changes. */</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2018 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Author: Neels Hofmeyr <neels@hofmeyr.de></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/fsm.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* a = return_val * b. Return 0 if factor is below 1. */</span><br><span style="color: hsl(0, 100%, 40%);">-static int T_factor(enum T_unit a, enum T_unit b)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- if (b == a</span><br><span style="color: hsl(0, 100%, 40%);">-          || b == T_CUSTOM || a == T_CUSTOM)</span><br><span style="color: hsl(0, 100%, 40%);">-          return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (b) {</span><br><span style="color: hsl(0, 100%, 40%);">-    case T_MS:</span><br><span style="color: hsl(0, 100%, 40%);">-              switch (a) {</span><br><span style="color: hsl(0, 100%, 40%);">-            case T_S:</span><br><span style="color: hsl(0, 100%, 40%);">-                       return 1000;</span><br><span style="color: hsl(0, 100%, 40%);">-            case T_M:</span><br><span style="color: hsl(0, 100%, 40%);">-                       return 60*1000;</span><br><span style="color: hsl(0, 100%, 40%);">-         default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       case T_S:</span><br><span style="color: hsl(0, 100%, 40%);">-               switch (a) {</span><br><span style="color: hsl(0, 100%, 40%);">-            case T_M:</span><br><span style="color: hsl(0, 100%, 40%);">-                       return 60;</span><br><span style="color: hsl(0, 100%, 40%);">-              default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int T_round(int val, enum T_unit from_unit, enum T_unit to_unit)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int f;</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!val)</span><br><span style="color: hsl(0, 100%, 40%);">-               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       f = T_factor(from_unit, to_unit);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (f < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-         f = T_factor(to_unit, from_unit);</span><br><span style="color: hsl(0, 100%, 40%);">-               return (val / f) + (val % f? 1 : 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       return val * f;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Return the value of a T timer from a list of T_defs.</span><br><span style="color: hsl(0, 100%, 40%);">- * Any value is rounded up to match as_unit: 1100 ms as T_S becomes 2 seconds, as T_M becomes one minute.</span><br><span style="color: hsl(0, 100%, 40%);">- * If no such timer is defined, return the default value passed, or abort the program if default < 0.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Usage examples:</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * - Initialization:</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- *  struct T_def global_T_defs[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- *              { .T=7, .default_val=50, .desc="Water Boiling Timeout" },  // default is .unit=T_S == 0</span><br><span style="color: hsl(0, 100%, 40%);">- *             { .T=8, .default_val=300, .desc="Tea brewing" },</span><br><span style="color: hsl(0, 100%, 40%);">- *            { .T=9, .default_val=5, .unit=T_M, .desc="Let tea cool down before drinking" },</span><br><span style="color: hsl(0, 100%, 40%);">- *             { .T=10, .default_val=20, .unit=T_M, .desc="Forgot to drink tea while it's warm" },</span><br><span style="color: hsl(0, 100%, 40%);">- *             {}  //  <-- important! last entry shall be zero</span><br><span style="color: hsl(0, 100%, 40%);">- *    };</span><br><span style="color: hsl(0, 100%, 40%);">- *    T_defs_reset(global_T_defs); // make all values the default</span><br><span style="color: hsl(0, 100%, 40%);">- *   T_defs_vty_init(global_T_defs, CONFIG_NODE);</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- *        val = T_def_get(global_T_defs, 7, T_S, -1); // -> 50</span><br><span style="color: hsl(0, 100%, 40%);">- *       sleep(val);</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- *         val = T_def_get(global_T_defs, 7, T_M, -1); // 50 seconds becomes 1 minute -> 1</span><br><span style="color: hsl(0, 100%, 40%);">- *    sleep_minutes(val);</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- *         val = T_def_get(global_T_defs, 99, T_S, -1); // not defined, program aborts!</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- *        val = T_def_get(global_T_defs, 99, T_S, 3); // not defined, returns 3</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-int T_def_get(const struct T_def *T_defs, int T, enum T_unit as_unit, int val_if_not_present)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  const struct T_def *d = T_def_get_entry((struct T_def*)T_defs, T);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!d) {</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_ASSERT(val_if_not_present >= 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                return val_if_not_present;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       return T_round(d->val, d->unit, as_unit);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Set all T_def values to the default_val. */</span><br><span style="color: hsl(0, 100%, 40%);">-void T_defs_reset(struct T_def *T_defs)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct T_def *d;</span><br><span style="color: hsl(0, 100%, 40%);">-        for_each_T_def(d, T_defs)</span><br><span style="color: hsl(0, 100%, 40%);">-               d->val = d->default_val;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Return a pointer to a T_def from an array, or NULL. */</span><br><span style="color: hsl(0, 100%, 40%);">-struct T_def *T_def_get_entry(struct T_def *T_defs, int T)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct T_def *d;</span><br><span style="color: hsl(0, 100%, 40%);">-        for_each_T_def(d, T_defs) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (d->T == T)</span><br><span style="color: hsl(0, 100%, 40%);">-                       return d;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Return a state_timeout entry from an array, or return NULL if the entry is zero.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * The timeouts_array shall contain exactly 32 elements, which corresponds to the number of states</span><br><span style="color: hsl(0, 100%, 40%);">- * allowed by osmo_fsm_*. Lookup is by array index.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * For example:</span><br><span style="color: hsl(0, 100%, 40%);">- *      struct state_timeout my_fsm_timeouts[32] = {</span><br><span style="color: hsl(0, 100%, 40%);">- *          [MY_FSM_STATE_3] = { .T = 423 },</span><br><span style="color: hsl(0, 100%, 40%);">- *              [MY_FSM_STATE_7] = { .T = 235 },</span><br><span style="color: hsl(0, 100%, 40%);">- *              [MY_FSM_STATE_8] = { .keep_timer = true },</span><br><span style="color: hsl(0, 100%, 40%);">- *            // any state that is omitted will remain zero == no timeout</span><br><span style="color: hsl(0, 100%, 40%);">- *   };</span><br><span style="color: hsl(0, 100%, 40%);">- *    get_state_timeout(MY_FSM_STATE_0, &my_fsm_timeouts) -> NULL,</span><br><span style="color: hsl(0, 100%, 40%);">- *   get_state_timeout(MY_FSM_STATE_7, &my_fsm_timeouts) -> { .T = 235 }</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * The intention is then to obtain the timer like T_def_get(global_T_defs, T=235); see also</span><br><span style="color: hsl(0, 100%, 40%);">- * fsm_inst_state_chg_T() below.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-const struct state_timeout *get_state_timeout(uint32_t state,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       const struct state_timeout *timeouts_array)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      const struct state_timeout *t;</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(state < 32);</span><br><span style="color: hsl(0, 100%, 40%);">-     t = &timeouts_array[state];</span><br><span style="color: hsl(0, 100%, 40%);">- if (!t->keep_timer && !t->T)</span><br><span style="color: hsl(0, 100%, 40%);">-              return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    return t;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Call osmo_fsm_inst_state_chg() or osmo_fsm_inst_state_chg_keep_timer(), depending on the T value</span><br><span style="color: hsl(0, 100%, 40%);">- * defined for this state in the timeouts_array, and obtaining the actual timeout value from T_defs.</span><br><span style="color: hsl(0, 100%, 40%);">- * A T timer configured in sub-second precision is rounded up to the next full second.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * See get_state_timeout() and T_def_get().</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Should a T number be defined in timeouts_array that is not defined in T_defs, use default_timeout.</span><br><span style="color: hsl(0, 100%, 40%);">- * This is best used by wrapping this function call in a macro suitable for a specific FSM</span><br><span style="color: hsl(0, 100%, 40%);">- * implementation, which can become as short as: my_fsm_state_chg(fi, NEXT_STATE):</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * #define my_fsm_state_chg(fi, NEXT_STATE) \</span><br><span style="color: hsl(0, 100%, 40%);">- *        fsm_inst_state_chg_T(fi, NEXT_STATE, my_fsm_timeouts, global_T_defs, 5)</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * my_fsm_state_chg(fi, MY_FSM_STATE_1);</span><br><span style="color: hsl(0, 100%, 40%);">- * // -> No timeout configured, will enter state without timeout.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * my_fsm_state_chg(fi, MY_FSM_STATE_3);</span><br><span style="color: hsl(0, 100%, 40%);">- * // T423 configured for this state, will look up T423 in T_defs, or use 5 seconds if unset.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * my_fsm_state_chg(fi, MY_FSM_STATE_8);</span><br><span style="color: hsl(0, 100%, 40%);">- * // keep_timer configured for this state, will invoke osmo_fsm_inst_state_chg_keep_timer().</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-int _fsm_inst_state_chg_T(struct osmo_fsm_inst *fi, uint32_t state,</span><br><span style="color: hsl(0, 100%, 40%);">-                       const struct state_timeout *timeouts_array,</span><br><span style="color: hsl(0, 100%, 40%);">-                     const struct T_def *T_defs, int default_timeout,</span><br><span style="color: hsl(0, 100%, 40%);">-                        const char *file, int line)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  const struct state_timeout *t = get_state_timeout(state, timeouts_array);</span><br><span style="color: hsl(0, 100%, 40%);">-       int val;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* No timeout defined for this state? */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!t)</span><br><span style="color: hsl(0, 100%, 40%);">-         return _osmo_fsm_inst_state_chg(fi, state, 0, 0, file, line);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (t->keep_timer) {</span><br><span style="color: hsl(0, 100%, 40%);">-         int rc = _osmo_fsm_inst_state_chg_keep_timer(fi, state, file, line);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (t->T && !rc)</span><br><span style="color: hsl(0, 100%, 40%);">-                     fi->T = t->T;</span><br><span style="color: hsl(0, 100%, 40%);">-             return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       val = T_def_get(T_defs, t->T, T_S, default_timeout);</span><br><span style="color: hsl(0, 100%, 40%);">- return _osmo_fsm_inst_state_chg(fi, state, val, t->T, file, line);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const struct value_string T_unit_names[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-      { T_S, "s" },</span><br><span style="color: hsl(0, 100%, 40%);">- { T_MS, "ms" },</span><br><span style="color: hsl(0, 100%, 40%);">-       { T_CUSTOM, "(custom)" },</span><br><span style="color: hsl(0, 100%, 40%);">-     { 0, NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span>diff --git a/src/osmo-bsc/gsm_timers_vty.c b/src/osmo-bsc/gsm_timers_vty.c</span><br><span>deleted file mode 100644</span><br><span>index e744dfa..0000000</span><br><span>--- a/src/osmo-bsc/gsm_timers_vty.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,118 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Implementation to configure Tnnn timers in VTY */</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2018 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Author: Neels Hofmeyr <neels@hofmeyr.de></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/vty/vty.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/vty/command.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Global singleton list used for the VTY configuration. See T_defs_vty_init(). */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct T_def *g_vty_T_defs = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Parse an argument like "T1234", "t1234" or "1234" and return the corresponding T_def entry from</span><br><span style="color: hsl(0, 100%, 40%);">- * g_vty_T_defs, if any. */</span><br><span style="color: hsl(0, 100%, 40%);">-struct T_def *parse_T_arg(struct vty *vty, const char *T_str)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       int T;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct T_def *d;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (T_str[0] == 't' || T_str[0] == 'T')</span><br><span style="color: hsl(0, 100%, 40%);">-         T_str++;</span><br><span style="color: hsl(0, 100%, 40%);">-        T = atoi(T_str);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        d = T_def_get_entry(g_vty_T_defs, T);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!d)</span><br><span style="color: hsl(0, 100%, 40%);">-         vty_out(vty, "No such timer: T%d%s", T, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">- return d;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Installed in the VTY on T_defs_vty_init(). */</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_timer, cfg_timer_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "timer TNNNN (default|<1-65535>)",</span><br><span style="color: hsl(0, 100%, 40%);">-      "Configure GSM Timers\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "T-number, optionally preceded by 't' or 'T'."</span><br><span style="color: hsl(0, 100%, 40%);">-      "See also 'show timer' for a list of available timers.\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Set to default timer value\n" "Timer value\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      const char *val_str = argv[1];</span><br><span style="color: hsl(0, 100%, 40%);">-  struct T_def *d;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        d = parse_T_arg(vty, argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!d)</span><br><span style="color: hsl(0, 100%, 40%);">-         return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!strcmp(val_str, "default"))</span><br><span style="color: hsl(0, 100%, 40%);">-              d->val = d->default_val;</span><br><span style="color: hsl(0, 100%, 40%);">-  else</span><br><span style="color: hsl(0, 100%, 40%);">-            d->val = atoi(val_str);</span><br><span style="color: hsl(0, 100%, 40%);">-      vty_out(vty, "T%d = %u %s (%s)%s", d->T, d->val, T_unit_name(d->unit), d->desc, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-     return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Print a T_def to the VTY. */</span><br><span style="color: hsl(0, 100%, 40%);">-static void show_one_timer(struct vty *vty, struct T_def *d)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        vty_out(vty, "T%d = %u %s (default = %u %s) \t%s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-          d->T, d->val, T_unit_name(d->unit),</span><br><span style="color: hsl(0, 100%, 40%);">-            d->default_val, T_unit_name(d->unit), d->desc, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Installed in the VTY on T_defs_vty_init(). */</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(show_timer, show_timer_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "show timer [TNNNN]",</span><br><span style="color: hsl(0, 100%, 40%);">-      SHOW_STR "GSM Timers\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Specific timer to show, or all timers if omitted.\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct T_def *d;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (argc) {</span><br><span style="color: hsl(0, 100%, 40%);">-             d = parse_T_arg(vty, argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-          if (!d)</span><br><span style="color: hsl(0, 100%, 40%);">-                 return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-             show_one_timer(vty, d);</span><br><span style="color: hsl(0, 100%, 40%);">-         return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for_each_T_def(d, g_vty_T_defs)</span><br><span style="color: hsl(0, 100%, 40%);">-         show_one_timer(vty, d);</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Install GSM timer configuration commands in the VTY. */</span><br><span style="color: hsl(0, 100%, 40%);">-void T_defs_vty_init(struct T_def *T_defs, int cfg_parent_node)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  g_vty_T_defs = T_defs;</span><br><span style="color: hsl(0, 100%, 40%);">-  install_element_ve(&show_timer_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-        install_element(cfg_parent_node, &cfg_timer_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Write GSM timer configuration to the vty. */</span><br><span style="color: hsl(0, 100%, 40%);">-void T_defs_vty_write(struct vty *vty, const char *indent)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct T_def *d;</span><br><span style="color: hsl(0, 100%, 40%);">-        for_each_T_def(d, g_vty_T_defs) {</span><br><span style="color: hsl(0, 100%, 40%);">-               if (d->val != d->default_val)</span><br><span style="color: hsl(0, 100%, 40%);">-                     vty_out(vty, "%stimer t%d %u%s", indent, d->T, d->val, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c</span><br><span>index 421c32e..fe3b8b2 100644</span><br><span>--- a/src/osmo-bsc/handover_fsm.c</span><br><span>+++ b/src/osmo-bsc/handover_fsm.c</span><br><span>@@ -159,7 +159,7 @@</span><br><span>    return fi->priv;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static const struct state_timeout ho_fsm_timeouts[32] = {</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct osmo_tdef_state_timeout ho_fsm_timeouts[32] = {</span><br><span>   [HO_ST_WAIT_LCHAN_ACTIVE] = { .T = 23042 },</span><br><span>  [HO_ST_WAIT_RR_HO_DETECT] = { .T = 23042 },</span><br><span>  [HO_ST_WAIT_RR_HO_COMPLETE] = { .T = 23042 },</span><br><span>@@ -173,10 +173,10 @@</span><br><span>  * The actual timeout value is in turn obtained from network->T_defs.</span><br><span>  * Assumes local variable fi exists. */</span><br><span> #define ho_fsm_state_chg(state) \</span><br><span style="color: hsl(0, 100%, 40%);">-       fsm_inst_state_chg_T(fi, state, \</span><br><span style="color: hsl(0, 100%, 40%);">-                            ho_fsm_timeouts, \</span><br><span style="color: hsl(0, 100%, 40%);">-                      ((struct gsm_subscriber_connection*)(fi->priv))->network->T_defs, \</span><br><span style="color: hsl(0, 100%, 40%);">-                            5)</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_tdef_fsm_inst_state_chg(fi, state, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                  ho_fsm_timeouts, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                    ((struct gsm_subscriber_connection*)(fi->priv))->network->T_defs, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                  5)</span><br><span> </span><br><span> /* Log failure and transition to HO_ST_FAILURE, which triggers the appropriate actions. */</span><br><span> #define ho_fail(result, fmt, args...) do { \</span><br><span>diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c</span><br><span>index 7af2ea0..33abb1f 100644</span><br><span>--- a/src/osmo-bsc/lchan_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_fsm.c</span><br><span>@@ -207,7 +207,7 @@</span><br><span>         }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct state_timeout lchan_fsm_timeouts[32] = {</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_tdef_state_timeout lchan_fsm_timeouts[32] = {</span><br><span>         [LCHAN_ST_WAIT_TS_READY]        = { .T=23001 },</span><br><span>      [LCHAN_ST_WAIT_ACTIV_ACK]       = { .T=23002 },</span><br><span>      [LCHAN_ST_WAIT_RLL_RTP_ESTABLISH]       = { .T=3101 },</span><br><span>@@ -221,10 +221,10 @@</span><br><span>  * The actual timeout value is in turn obtained from network->T_defs.</span><br><span>  * Assumes local variable fi exists. */</span><br><span> #define lchan_fsm_state_chg(state) \</span><br><span style="color: hsl(0, 100%, 40%);">-   fsm_inst_state_chg_T(fi, state, \</span><br><span style="color: hsl(0, 100%, 40%);">-                            lchan_fsm_timeouts, \</span><br><span style="color: hsl(0, 100%, 40%);">-                           ((struct gsm_lchan*)(fi->priv))->ts->trx->bts->network->T_defs, \</span><br><span style="color: hsl(0, 100%, 40%);">-                             5)</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_tdef_fsm_inst_state_chg(fi, state, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                  lchan_fsm_timeouts, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                 ((struct gsm_lchan*)(fi->priv))->ts->trx->bts->network->T_defs, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                   5)</span><br><span> </span><br><span> /* Set a failure message, trigger the common actions to take on failure, transition to a state to</span><br><span>  * continue with (using state timeouts from lchan_fsm_timeouts[]). Assumes local variable fi exists. */</span><br><span>diff --git a/src/osmo-bsc/lchan_rtp_fsm.c b/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>index 2d15bf2..5e2d758 100644</span><br><span>--- a/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>@@ -23,7 +23,6 @@</span><br><span> #include <osmocom/core/fsm.h></span><br><span> </span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> #include <osmocom/bsc/lchan_rtp_fsm.h></span><br><span> #include <osmocom/bsc/mgw_endpoint_fsm.h></span><br><span>@@ -41,7 +40,7 @@</span><br><span>       return fi->priv;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct state_timeout lchan_rtp_fsm_timeouts[32] = {</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_tdef_state_timeout lchan_rtp_fsm_timeouts[32] = {</span><br><span>       [LCHAN_RTP_ST_WAIT_MGW_ENDPOINT_AVAILABLE] = { .T=23004 },</span><br><span>   [LCHAN_RTP_ST_WAIT_IPACC_CRCX_ACK]      = { .T=23005 },</span><br><span>      [LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK]      = { .T=23006 },</span><br><span>@@ -52,10 +51,10 @@</span><br><span>  * The actual timeout value is in turn obtained from network->T_defs.</span><br><span>  * Assumes local variable fi exists. */</span><br><span> #define lchan_rtp_fsm_state_chg(state) \</span><br><span style="color: hsl(0, 100%, 40%);">-        fsm_inst_state_chg_T(fi, state, \</span><br><span style="color: hsl(0, 100%, 40%);">-                            lchan_rtp_fsm_timeouts, \</span><br><span style="color: hsl(0, 100%, 40%);">-                       ((struct gsm_lchan*)(fi->priv))->ts->trx->bts->network->T_defs, \</span><br><span style="color: hsl(0, 100%, 40%);">-                             5)</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_tdef_fsm_inst_state_chg(fi, state, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                  lchan_rtp_fsm_timeouts, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                     ((struct gsm_lchan*)(fi->priv))->ts->trx->bts->network->T_defs, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                   5)</span><br><span> </span><br><span> /* Set a failure message, trigger the common actions to take on failure, transition to a state to</span><br><span>  * continue with (using state timeouts from lchan_rtp_fsm_timeouts[]). Assumes local variable fi exists. */</span><br><span>diff --git a/src/osmo-bsc/mgw_endpoint_fsm.c b/src/osmo-bsc/mgw_endpoint_fsm.c</span><br><span>index 5462914..fa65166 100644</span><br><span>--- a/src/osmo-bsc/mgw_endpoint_fsm.c</span><br><span>+++ b/src/osmo-bsc/mgw_endpoint_fsm.c</span><br><span>@@ -29,7 +29,6 @@</span><br><span> #include <osmocom/netif/rtp.h></span><br><span> </span><br><span> #include <osmocom/bsc/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> </span><br><span> #include <osmocom/bsc/mgw_endpoint_fsm.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span>@@ -196,9 +195,9 @@</span><br><span>   }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct T_def *g_T_defs = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_tdef *g_T_defs = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void mgw_endpoint_fsm_init(struct T_def *T_defs)</span><br><span style="color: hsl(120, 100%, 40%);">+void mgw_endpoint_fsm_init(struct osmo_tdef *T_defs)</span><br><span> {</span><br><span>    g_T_defs = T_defs;</span><br><span>   OSMO_ASSERT(osmo_fsm_register(&mgwep_fsm) == 0);</span><br><span>@@ -380,7 +379,7 @@</span><br><span> }</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static const struct state_timeout mgwep_fsm_timeouts[32] = {</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct osmo_tdef_state_timeout mgwep_fsm_timeouts[32] = {</span><br><span>  [MGWEP_ST_WAIT_MGW_RESPONSE] = { .T=23042 },</span><br><span> };</span><br><span> </span><br><span>@@ -388,7 +387,7 @@</span><br><span>  * The actual timeout value is in turn obtained from g_T_defs.</span><br><span>  * Assumes local variable fi exists. */</span><br><span> #define mgwep_fsm_state_chg(state) \</span><br><span style="color: hsl(0, 100%, 40%);">-       fsm_inst_state_chg_T(fi, state, mgwep_fsm_timeouts, g_T_defs, 5)</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_tdef_fsm_inst_state_chg(fi, state, mgwep_fsm_timeouts, g_T_defs, 5)</span><br><span> </span><br><span> void mgw_endpoint_ci_request(struct mgwep_ci *ci,</span><br><span>                         enum mgcp_verb verb, const struct mgcp_conn_peer *verb_info,</span><br><span>diff --git a/src/osmo-bsc/net_init.c b/src/osmo-bsc/net_init.c</span><br><span>index b4ff489..c2a38bc 100644</span><br><span>--- a/src/osmo-bsc/net_init.c</span><br><span>+++ b/src/osmo-bsc/net_init.c</span><br><span>@@ -17,21 +17,22 @@</span><br><span>  *</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/tdef.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/bsc/osmo_bsc.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span> #include <osmocom/bsc/handover_cfg.h></span><br><span> #include <osmocom/bsc/chan_alloc.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct T_def gsm_network_T_defs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_tdef gsm_network_T_defs[] = {</span><br><span>  { .T=7, .default_val=10, .desc="inter-BSC Handover MO, HO Required to HO Command" },</span><br><span>       { .T=8, .default_val=10, .desc="inter-BSC Handover MO, HO Command to final Clear" },</span><br><span>       { .T=10, .default_val=6, .desc="RR Assignment" },</span><br><span>  { .T=101, .default_val=10, .desc="inter-BSC Handover MT, HO Request to HO Accept" },</span><br><span>       { .T=3101, .default_val=3, .desc="RR Immediate Assignment" },</span><br><span>      { .T=3103, .default_val=5, .desc="Handover" },</span><br><span style="color: hsl(0, 100%, 40%);">-        { .T=3105, .default_val=100, .unit=T_MS, .desc="Physical Information" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .T=3105, .default_val=100, .unit=OSMO_TDEF_MS, .desc="Physical Information" },</span><br><span>   { .T=3107, .default_val=5, .desc="(unused)" },</span><br><span>     { .T=3109, .default_val=5, .desc="RSL SACCH deactivation" },</span><br><span>       { .T=3111, .default_val=2, .desc="Wait time before RSL RF Channel Release" },</span><br><span>@@ -42,7 +43,7 @@</span><br><span>  { .T=3119, .default_val=10, .desc="(unused)" },</span><br><span>    { .T=3122, .default_val=GSM_T3122_DEFAULT, .desc="Wait time after RR Immediate Assignment Reject" },</span><br><span>       { .T=3141, .default_val=10, .desc="(unused)" },</span><br><span style="color: hsl(0, 100%, 40%);">-       { .T=3212, .default_val=5, .unit=T_CUSTOM,</span><br><span style="color: hsl(120, 100%, 40%);">+    { .T=3212, .default_val=5, .unit=OSMO_TDEF_CUSTOM,</span><br><span>           .desc="Periodic Location Update timer, sent to MS (1 = 6 minutes)" },</span><br><span>      { .T=993210, .default_val=20, .desc="After L3 Complete, wait for MSC to confirm" },</span><br><span>        { .T=999, .default_val=60, .desc="After Clear Request, wait for MSC to Clear Command (sanity)" },</span><br><span>@@ -78,7 +79,7 @@</span><br><span>      net->num_bts = 0;</span><br><span> </span><br><span>     net->T_defs = gsm_network_T_defs;</span><br><span style="color: hsl(0, 100%, 40%);">-    T_defs_reset(net->T_defs);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_tdefs_reset(net->T_defs);</span><br><span> </span><br><span>        return net;</span><br><span> }</span><br><span>diff --git a/src/osmo-bsc/paging.c b/src/osmo-bsc/paging.c</span><br><span>index 066db1c..f1fd2ad 100644</span><br><span>--- a/src/osmo-bsc/paging.c</span><br><span>+++ b/src/osmo-bsc/paging.c</span><br><span>@@ -39,6 +39,7 @@</span><br><span> #include <assert.h></span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/tdef.h></span><br><span> #include <osmocom/gsm/gsm48.h></span><br><span> #include <osmocom/gsm/gsm0502.h></span><br><span> </span><br><span>@@ -51,7 +52,6 @@</span><br><span> #include <osmocom/bsc/chan_alloc.h></span><br><span> #include <osmocom/bsc/gsm_08_08.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> </span><br><span> void *tall_paging_ctx = NULL;</span><br><span>@@ -294,11 +294,11 @@</span><br><span> static unsigned int calculate_timer_3113(struct gsm_bts *bts)</span><br><span> {</span><br><span>   unsigned int to_us, to;</span><br><span style="color: hsl(0, 100%, 40%);">- struct T_def *d = T_def_get_entry(bts->network->T_defs, 3113);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_tdef *d = osmo_tdef_get_entry(bts->network->T_defs, 3113);</span><br><span> </span><br><span>     /* Note: d should always contain a valid pointer since all timers,</span><br><span>    * including 3113 are statically pre-defined in</span><br><span style="color: hsl(0, 100%, 40%);">-  * struct T_def gsm_network_T_defs. */</span><br><span style="color: hsl(120, 100%, 40%);">+         * struct osmo_tdef gsm_network_T_defs. */</span><br><span>   OSMO_ASSERT(d);</span><br><span> </span><br><span>  if (!bts->T3113_dynamic)</span><br><span>diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am</span><br><span>index 24cd230..e585e0d 100644</span><br><span>--- a/src/utils/Makefile.am</span><br><span>+++ b/src/utils/Makefile.am</span><br><span>@@ -51,7 +51,6 @@</span><br><span>     $(top_builddir)/src/osmo-bsc/bts_siemens_bs11.o \</span><br><span>    $(top_builddir)/src/osmo-bsc/e1_config.o \</span><br><span>   $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/net_init.o \</span><br><span>    $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOGSM_LIBS) \</span><br><span>@@ -119,7 +118,6 @@</span><br><span> </span><br><span> meas_json_LDADD = \</span><br><span>        $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOGSM_LIBS) \</span><br><span>         $(LIBOSMOABIS_LIBS) \</span><br><span>diff --git a/tests/abis/Makefile.am b/tests/abis/Makefile.am</span><br><span>index 4fc3605..60054d9 100644</span><br><span>--- a/tests/abis/Makefile.am</span><br><span>+++ b/tests/abis/Makefile.am</span><br><span>@@ -27,7 +27,6 @@</span><br><span> abis_test_LDADD = \</span><br><span>        $(top_builddir)/src/osmo-bsc/abis_nm.o \</span><br><span>     $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/net_init.o \</span><br><span>    $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOABIS_LIBS) \</span><br><span>diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am</span><br><span>index c8ad0e4..b301f9e 100644</span><br><span>--- a/tests/bsc/Makefile.am</span><br><span>+++ b/tests/bsc/Makefile.am</span><br><span>@@ -38,7 +38,6 @@</span><br><span>   $(top_builddir)/src/osmo-bsc/osmo_bsc_filter.o \</span><br><span>     $(top_builddir)/src/osmo-bsc/bsc_subscriber.o \</span><br><span>      $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/handover_cfg.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/handover_logic.o \</span><br><span>      $(top_builddir)/src/osmo-bsc/neighbor_ident.o \</span><br><span>diff --git a/tests/gsm0408/Makefile.am b/tests/gsm0408/Makefile.am</span><br><span>index b207f8b..aff7c7d 100644</span><br><span>--- a/tests/gsm0408/Makefile.am</span><br><span>+++ b/tests/gsm0408/Makefile.am</span><br><span>@@ -26,7 +26,6 @@</span><br><span>         $(top_builddir)/src/osmo-bsc/gsm_04_08_rr.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/net_init.o \</span><br><span>    $(top_builddir)/src/osmo-bsc/rest_octets.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/system_information.o \</span><br><span>diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am</span><br><span>index 5e4440c..40ecf54 100644</span><br><span>--- a/tests/handover/Makefile.am</span><br><span>+++ b/tests/handover/Makefile.am</span><br><span>@@ -55,7 +55,6 @@</span><br><span>         $(top_builddir)/src/osmo-bsc/gsm_04_08_rr.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/gsm_04_80_utils.o \</span><br><span>     $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/handover_cfg.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/handover_decision.o \</span><br><span>   $(top_builddir)/src/osmo-bsc/handover_decision_2.o \</span><br><span>diff --git a/tests/nanobts_omlattr/Makefile.am b/tests/nanobts_omlattr/Makefile.am</span><br><span>index 312cf7d..aa7045e 100644</span><br><span>--- a/tests/nanobts_omlattr/Makefile.am</span><br><span>+++ b/tests/nanobts_omlattr/Makefile.am</span><br><span>@@ -26,7 +26,6 @@</span><br><span>    $(top_builddir)/src/osmo-bsc/abis_nm.o \</span><br><span>     $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/osmo-bsc/gsm_timers.o \</span><br><span>  $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOGSM_LIBS) \</span><br><span>         $(LIBOSMOABIS_LIBS) \</span><br><span>diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>index 38729ac..65eb055 100644</span><br><span>--- a/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>+++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>@@ -21,7 +21,6 @@</span><br><span> </span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/bts_ipaccess_nanobts_omlattr.h></span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span>@@ -192,9 +191,9 @@</span><br><span>    .num_cat = ARRAY_SIZE(log_categories),</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct T_def gsm_network_T_defs[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-    { .T=3105, .default_val=100, .val=13, .unit=T_MS, .desc="Physical Information" },</span><br><span style="color: hsl(0, 100%, 40%);">-     { .T=3212, .default_val=5, .unit=T_CUSTOM,</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_tdef gsm_network_T_defs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+  { .T=3105, .default_val=100, .val=13, .unit=OSMO_TDEF_MS, .desc="Physical Information" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { .T=3212, .default_val=5, .unit=OSMO_TDEF_CUSTOM,</span><br><span>           .desc="Periodic Location Update timer, sent to MS (1 = 6 minutes)" },</span><br><span>      {}</span><br><span> };</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13795">change 13795</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13795"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I66674a5d8403d820038762888c846bae10ceac58 </div>
<div style="display:none"> Gerrit-Change-Number: 13795 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>