<p>daniel has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/22446">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">WIP: Tracing<br><br>Change-Id: I78945ab2bde7c93e9461dc446809f7cbd6493100<br>---<br>M include/osmocom/core/fsm.h<br>M include/osmocom/core/logging.h<br>M include/osmocom/core/tdef.h<br>M src/fsm.c<br>M src/gb/gprs_ns2_vc_fsm.c<br>M src/logging.c<br>M src/tdef.c<br>7 files changed, 160 insertions(+), 52 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/46/22446/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h</span><br><span>index 77ebe7c..9ff5873 100644</span><br><span>--- a/include/osmocom/core/fsm.h</span><br><span>+++ b/include/osmocom/core/fsm.h</span><br><span>@@ -202,6 +202,34 @@</span><br><span> #define OSMO_T_FMT "%c%u"</span><br><span> #define OSMO_T_FMT_ARGS(T) ((T) >= 0 ? 'T' : 'X'), ((T) >= 0 ? T : -T)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* FSM Tracing Macros */</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPFSMENTSRC(fi, file, line, func, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPSRC((fi)->fsm->log_subsys, TRACEOP_ENTFUN, \</span><br><span style="color: hsl(120, 100%, 40%);">+ file, line, func, \</span><br><span style="color: hsl(120, 100%, 40%);">+ "fsminst=%p name=%s id=%s state=%s%s" fmt, fi, \</span><br><span style="color: hsl(120, 100%, 40%);">+ (fi)->fsm->name, (fi)->id, \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_state_name((fi)->fsm, (fi)->state), \</span><br><span style="color: hsl(120, 100%, 40%);">+ fmt[0] ? " " : "", ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPFSMEXTSRC(fi, file, line, func, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPSRC((fi)->fsm->log_subsys, TRACEOP_EXTFUN, \</span><br><span style="color: hsl(120, 100%, 40%);">+ file, line, func, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPFSMATTRSRC(fi, file, line, func, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPSRC((fi)->fsm->log_subsys, TRACEOP_ATTR, \</span><br><span style="color: hsl(120, 100%, 40%);">+ file, line, func, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPFSMENT(fi, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEP((fi)->fsm->log_subsys, TRACEOP_ENTFUN, \</span><br><span style="color: hsl(120, 100%, 40%);">+ "fsminst=%p name=%s id=%s state=%s%s" fmt, fi, \</span><br><span style="color: hsl(120, 100%, 40%);">+ (fi)->fsm->name, (fi)->id, \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_state_name((fi)->fsm, (fi)->state), \</span><br><span style="color: hsl(120, 100%, 40%);">+ fmt[0] ? " " : "", ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPFSMEXT(fi, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEP((fi)->fsm->log_subsys, TRACEOP_EXTFUN, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPFSMATTR(fi, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEP((fi)->fsm->log_subsys, TRACEOP_ATTR, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int osmo_fsm_register(struct osmo_fsm *fsm);</span><br><span> void osmo_fsm_unregister(struct osmo_fsm *fsm);</span><br><span> struct osmo_fsm *osmo_fsm_find_by_name(const char *name);</span><br><span>@@ -240,17 +268,17 @@</span><br><span> */</span><br><span> #define osmo_fsm_inst_state_chg(fi, new_state, timeout_secs, T) \</span><br><span> _osmo_fsm_inst_state_chg(fi, new_state, timeout_secs, T, \</span><br><span style="color: hsl(0, 100%, 40%);">- __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ __FILE__, __LINE__, __func__)</span><br><span> int _osmo_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_secs, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> #define osmo_fsm_inst_state_chg_ms(fi, new_state, timeout_ms, T) \</span><br><span> _osmo_fsm_inst_state_chg_ms(fi, new_state, timeout_ms, T, \</span><br><span style="color: hsl(0, 100%, 40%);">- __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ __FILE__, __LINE__, __func__)</span><br><span> int _osmo_fsm_inst_state_chg_ms(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_ms, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> /*! perform a state change while keeping the current timer running.</span><br><span> *</span><br><span>@@ -263,9 +291,9 @@</span><br><span> */</span><br><span> #define osmo_fsm_inst_state_chg_keep_timer(fi, new_state) \</span><br><span> _osmo_fsm_inst_state_chg_keep_timer(fi, new_state, \</span><br><span style="color: hsl(0, 100%, 40%);">- __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ __FILE__, __LINE__, __func__)</span><br><span> int _osmo_fsm_inst_state_chg_keep_timer(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> /*! perform a state change while keeping the current timer if running, or starting a timer otherwise.</span><br><span> *</span><br><span>@@ -277,17 +305,17 @@</span><br><span> */</span><br><span> #define osmo_fsm_inst_state_chg_keep_or_start_timer(fi, new_state, timeout_secs, T) \</span><br><span> _osmo_fsm_inst_state_chg_keep_or_start_timer(fi, new_state, timeout_secs, T, \</span><br><span style="color: hsl(0, 100%, 40%);">- __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ __FILE__, __LINE__, __func__)</span><br><span> int _osmo_fsm_inst_state_chg_keep_or_start_timer(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_secs, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> #define osmo_fsm_inst_state_chg_keep_or_start_timer_ms(fi, new_state, timeout_ms, T) \</span><br><span> _osmo_fsm_inst_state_chg_keep_or_start_timer_ms(fi, new_state, timeout_ms, T, \</span><br><span style="color: hsl(0, 100%, 40%);">- __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ __FILE__, __LINE__, __func__)</span><br><span> int _osmo_fsm_inst_state_chg_keep_or_start_timer_ms(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_ms, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> </span><br><span> /*! dispatch an event to an osmocom finite state machine instance</span><br><span>@@ -297,9 +325,9 @@</span><br><span> * purposes. See there for documentation.</span><br><span> */</span><br><span> #define osmo_fsm_inst_dispatch(fi, event, data) \</span><br><span style="color: hsl(0, 100%, 40%);">- _osmo_fsm_inst_dispatch(fi, event, data, __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ _osmo_fsm_inst_dispatch(fi, event, data, __FILE__, __LINE__, __func__)</span><br><span> int _osmo_fsm_inst_dispatch(struct osmo_fsm_inst *fi, uint32_t event, void *data,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> /*! Terminate FSM instance with given cause</span><br><span> *</span><br><span>@@ -308,10 +336,10 @@</span><br><span> * See there for documentation.</span><br><span> */</span><br><span> #define osmo_fsm_inst_term(fi, cause, data) \</span><br><span style="color: hsl(0, 100%, 40%);">- _osmo_fsm_inst_term(fi, cause, data, __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ _osmo_fsm_inst_term(fi, cause, data, __FILE__, __LINE__, __func__)</span><br><span> void _osmo_fsm_inst_term(struct osmo_fsm_inst *fi,</span><br><span> enum osmo_fsm_term_cause cause, void *data,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> /*! Terminate all child FSM instances of an FSM instance.</span><br><span> *</span><br><span>@@ -320,11 +348,11 @@</span><br><span> * purposes. See there for documentation.</span><br><span> */</span><br><span> #define osmo_fsm_inst_term_children(fi, cause, data) \</span><br><span style="color: hsl(0, 100%, 40%);">- _osmo_fsm_inst_term_children(fi, cause, data, __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ _osmo_fsm_inst_term_children(fi, cause, data, __FILE__, __LINE__, __func__)</span><br><span> void _osmo_fsm_inst_term_children(struct osmo_fsm_inst *fi,</span><br><span> enum osmo_fsm_term_cause cause,</span><br><span> void *data,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> /*! dispatch an event to all children of an osmocom finite state machine instance</span><br><span> *</span><br><span>@@ -333,8 +361,8 @@</span><br><span> * purposes. See there for documentation.</span><br><span> */</span><br><span> #define osmo_fsm_inst_broadcast_children(fi, cause, data) \</span><br><span style="color: hsl(0, 100%, 40%);">- _osmo_fsm_inst_broadcast_children(fi, cause, data, __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ _osmo_fsm_inst_broadcast_children(fi, cause, data, __FILE__, __LINE__, __func__)</span><br><span> void _osmo_fsm_inst_broadcast_children(struct osmo_fsm_inst *fi, uint32_t event,</span><br><span style="color: hsl(0, 100%, 40%);">- void *data, const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ void *data, const char *file, int line, const char *func);</span><br><span> </span><br><span> /*! @} */</span><br><span>diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h</span><br><span>index c7f89de..d27c4a3 100644</span><br><span>--- a/include/osmocom/core/logging.h</span><br><span>+++ b/include/osmocom/core/logging.h</span><br><span>@@ -50,10 +50,7 @@</span><br><span> * \param[in] args variable argument list</span><br><span> */</span><br><span> #define LOGPC(ss, level, fmt, args...) \</span><br><span style="color: hsl(0, 100%, 40%);">- do { \</span><br><span style="color: hsl(0, 100%, 40%);">- if (log_check_level(ss, level)) \</span><br><span style="color: hsl(0, 100%, 40%);">- logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args); \</span><br><span style="color: hsl(0, 100%, 40%);">- } while(0)</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPSRCC(ss, level, NULL, 0, 1, fmt, ##args)</span><br><span> </span><br><span> /*! Log through the Osmocom logging framework with explicit source.</span><br><span> * If caller_file is passed as NULL, __FILE__ and __LINE__ are used</span><br><span>@@ -85,6 +82,7 @@</span><br><span> */</span><br><span> #define LOGPSRCC(ss, level, caller_file, caller_line, cont, fmt, args...) \</span><br><span> do { \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPEVTSRC(ss, level, caller_file, caller_line, __func__, fmt, ##args); \</span><br><span> if (log_check_level(ss, level)) {\</span><br><span> if (caller_file) \</span><br><span> logp2(ss, level, caller_file, caller_line, cont, fmt, ##args); \</span><br><span>@@ -93,6 +91,33 @@</span><br><span> }\</span><br><span> } while(0)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEOP_ENTFUN "ENTER"</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEOP_EXTFUN "EXIT"</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEOP_ATTR "ATTR"</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEOP_EVT "EVT"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEP(ss, oper, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPSRC(ss, oper, NULL, 0, (const char *)NULL, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPSRC(ss, oper, caller_file, caller_line, caller_func, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ do { \</span><br><span style="color: hsl(120, 100%, 40%);">+ if (log_check_level(DLTRACE, LOGL_DEBUG)) {\</span><br><span style="color: hsl(120, 100%, 40%);">+ if (caller_file) \</span><br><span style="color: hsl(120, 100%, 40%);">+ logp2(DLTRACE, LOGL_DEBUG, caller_file, caller_line, 0, "[" oper " func=%s ss=%02x]%s" fmt, caller_func, ss, fmt[0]?" ":"", ##args); \</span><br><span style="color: hsl(120, 100%, 40%);">+ else \</span><br><span style="color: hsl(120, 100%, 40%);">+ logp2(DLTRACE, LOGL_DEBUG, __FILE__, __LINE__, 0, "[" oper " func=%s ss=%02x]%s" fmt, __func__, ss, fmt[0]?" ":"", ##args); \</span><br><span style="color: hsl(120, 100%, 40%);">+ }\</span><br><span style="color: hsl(120, 100%, 40%);">+ } while(0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPENTFUN(ss, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEP(ss, TRACEOP_ENTFUN, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPEXTFUN(ss, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEP(ss, TRACEOP_EXTFUN, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPATTR(ss, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEP(ss, TRACEOP_ATTR, fmt, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+#define TRACEPEVTSRC(ss, level, caller_file, caller_line, caller_func, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPSRC(ss, TRACEOP_EVT, caller_file, caller_line, caller_func, "level=%02x " fmt, level, ##args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! different log levels */</span><br><span> #define LOGL_DEBUG 1 /*!< debugging information */</span><br><span> #define LOGL_INFO 3 /*!< general information */</span><br><span>@@ -122,7 +147,8 @@</span><br><span> #define DLRSPRO -19 /*!< Osmocom Remote SIM Protocol */</span><br><span> #define DLNS -20 /*!< Osmocom NS layer */</span><br><span> #define DLBSSGP -21 /*!< Osmocom BSSGP layer */</span><br><span style="color: hsl(0, 100%, 40%);">-#define OSMO_NUM_DLIB 21 /*!< Number of logging sub-systems in libraries */</span><br><span style="color: hsl(120, 100%, 40%);">+#define DLTRACE -22 /*!< Osmocom Tracing messages (intended for GSMTAP logging) */</span><br><span style="color: hsl(120, 100%, 40%);">+#define OSMO_NUM_DLIB 22 /*!< Number of logging sub-systems in libraries */</span><br><span> </span><br><span> /* Colors that can be used in log_info_cat.color */</span><br><span> #define OSMO_LOGCOLOR_NORMAL NULL</span><br><span>diff --git a/include/osmocom/core/tdef.h b/include/osmocom/core/tdef.h</span><br><span>index 627ba3f..a589d43 100644</span><br><span>--- a/include/osmocom/core/tdef.h</span><br><span>+++ b/include/osmocom/core/tdef.h</span><br><span>@@ -159,11 +159,11 @@</span><br><span> */</span><br><span> #define osmo_tdef_fsm_inst_state_chg(fi, state, timeouts_array, tdefs, default_timeout) \</span><br><span> _osmo_tdef_fsm_inst_state_chg(fi, state, timeouts_array, tdefs, default_timeout, \</span><br><span style="color: hsl(0, 100%, 40%);">- __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+ __FILE__, __LINE__, __func__)</span><br><span> int _osmo_tdef_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t state,</span><br><span> const struct osmo_tdef_state_timeout *timeouts_array,</span><br><span> const struct osmo_tdef *tdefs, unsigned long default_timeout,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func);</span><br><span> </span><br><span> /*! Manage timer definitions in named groups.</span><br><span> * This should be defined as an array with the final element kept fully zero-initialized,</span><br><span>diff --git a/src/fsm.c b/src/fsm.c</span><br><span>index f1dbb41..ebb9f97 100644</span><br><span>--- a/src/fsm.c</span><br><span>+++ b/src/fsm.c</span><br><span>@@ -319,14 +319,17 @@</span><br><span> struct osmo_fsm *fsm = fi->fsm;</span><br><span> int32_t T = fi->T;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "timer=" OSMO_T_FMT, OSMO_T_FMT_ARGS(fi->T));</span><br><span> LOGPFSM(fi, "Timeout of " OSMO_T_FMT "\n", OSMO_T_FMT_ARGS(fi->T));</span><br><span> </span><br><span> if (fsm->timer_cb) {</span><br><span> int rc = fsm->timer_cb(fi);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc != 1) {</span><br><span> /* We don't actually know whether fi exists anymore.</span><br><span> * Make sure to not access it and return right away. */</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "");</span><br><span> return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> /* The timer_cb told us to terminate, so we can safely assume</span><br><span> * that fi still exists. */</span><br><span> LOGPFSM(fi, "timer_cb requested termination\n");</span><br><span>@@ -335,6 +338,7 @@</span><br><span> </span><br><span> /* if timer_cb returns 1 or there is no timer_cb */</span><br><span> osmo_fsm_inst_term(fi, OSMO_FSM_TERM_TIMEOUT, &T);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "");</span><br><span> }</span><br><span> </span><br><span> /*! Change id of the FSM instance</span><br><span>@@ -453,6 +457,7 @@</span><br><span> fsm_free_or_steal(fi);</span><br><span> return NULL;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "fsm_alloc=1 fsm_parent=%p", ctx);</span><br><span> </span><br><span> INIT_LLIST_HEAD(&fi->proc.children);</span><br><span> INIT_LLIST_HEAD(&fi->proc.child);</span><br><span>@@ -460,6 +465,7 @@</span><br><span> </span><br><span> LOGPFSM(fi, "Allocated\n");</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> return fi;</span><br><span> }</span><br><span> </span><br><span>@@ -479,19 +485,20 @@</span><br><span> uint32_t parent_term_event)</span><br><span> {</span><br><span> struct osmo_fsm_inst *fi;</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(parent, "");</span><br><span> </span><br><span> fi = osmo_fsm_inst_alloc(fsm, parent, NULL, parent->log_level,</span><br><span> parent->id);</span><br><span> if (!fi) {</span><br><span> /* indicate immediate termination to caller */</span><br><span> osmo_fsm_inst_dispatch(parent, parent_term_event, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=error");</span><br><span> return NULL;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> LOGPFSM(fi, "is child of %s\n", osmo_fsm_inst_name(parent));</span><br><span> </span><br><span> osmo_fsm_inst_change_parent(fi, parent, parent_term_event);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> return fi;</span><br><span> }</span><br><span> </span><br><span>@@ -540,6 +547,9 @@</span><br><span> */</span><br><span> void osmo_fsm_inst_free(struct osmo_fsm_inst *fi)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t ss = fi->fsm->log_subsys;</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "fsm_free=1");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> osmo_timer_del(&fi->timer);</span><br><span> llist_del(&fi->list);</span><br><span> </span><br><span>@@ -554,6 +564,7 @@</span><br><span> LOGPFSM(fi, "Deferring deallocation\n");</span><br><span> </span><br><span> /* Don't free anything yet. Exit. */</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span>@@ -574,6 +585,8 @@</span><br><span> fsm_free_or_steal(fi);</span><br><span> }</span><br><span> fsm_term_safely.root_fi = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEP(ss, TRACEOP_EXTFUN, "status=ok");</span><br><span> }</span><br><span> </span><br><span> /*! get human-readable name of FSM event</span><br><span>@@ -623,17 +636,20 @@</span><br><span> </span><br><span> static int state_chg(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> bool keep_timer, unsigned long timeout_ms, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span> struct osmo_fsm *fsm = fi->fsm;</span><br><span> uint32_t old_state = fi->state;</span><br><span> const struct osmo_fsm_state *st = &fsm->states[fi->state];</span><br><span> struct timeval remaining;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENTSRC(fi, file, line, func, "new_state=%s T=%u tout_ms=%lu", osmo_fsm_state_name(fsm, new_state), T, timeout_ms);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (fi->proc.terminating) {</span><br><span> LOGPFSMSRC(fi, file, line,</span><br><span> "FSM instance already terminating, not changing state to %s\n",</span><br><span> osmo_fsm_state_name(fsm, new_state));</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXTSRC(fi, file, line, func, "status=error");</span><br><span> return -EINVAL;</span><br><span> }</span><br><span> </span><br><span>@@ -642,6 +658,7 @@</span><br><span> LOGPFSMLSRC(fi, LOGL_ERROR, file, line,</span><br><span> "transition to state %s not permitted!\n",</span><br><span> osmo_fsm_state_name(fsm, new_state));</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXTSRC(fi, file, line, func, "status=error Invalid transition");</span><br><span> return -EPERM;</span><br><span> }</span><br><span> </span><br><span>@@ -698,6 +715,7 @@</span><br><span> if (st->onenter)</span><br><span> st->onenter(fi, old_state);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXTSRC(fi, file, line, func, "status=ok");</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -743,15 +761,15 @@</span><br><span> */</span><br><span> int _osmo_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_secs, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return state_chg(fi, new_state, false, timeout_secs*1000, T, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ return state_chg(fi, new_state, false, timeout_secs*1000, T, file, line, func);</span><br><span> }</span><br><span> int _osmo_fsm_inst_state_chg_ms(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_ms, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return state_chg(fi, new_state, false, timeout_ms, T, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ return state_chg(fi, new_state, false, timeout_ms, T, file, line, func);</span><br><span> }</span><br><span> </span><br><span> /*! perform a state change while keeping the current timer running.</span><br><span>@@ -774,9 +792,9 @@</span><br><span> * \returns 0 on success; negative on error</span><br><span> */</span><br><span> int _osmo_fsm_inst_state_chg_keep_timer(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return state_chg(fi, new_state, true, 0, 0, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ return state_chg(fi, new_state, true, 0, 0, file, line, func);</span><br><span> }</span><br><span> </span><br><span> /*! perform a state change while keeping the current timer if running, or starting a timer otherwise.</span><br><span>@@ -803,15 +821,15 @@</span><br><span> */</span><br><span> int _osmo_fsm_inst_state_chg_keep_or_start_timer(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_secs, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char* func)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return state_chg(fi, new_state, true, timeout_secs*1000, T, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ return state_chg(fi, new_state, true, timeout_secs*1000, T, file, line, func);</span><br><span> }</span><br><span> int _osmo_fsm_inst_state_chg_keep_or_start_timer_ms(struct osmo_fsm_inst *fi, uint32_t new_state,</span><br><span> unsigned long timeout_ms, int T,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return state_chg(fi, new_state, true, timeout_ms, T, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ return state_chg(fi, new_state, true, timeout_ms, T, file, line, func);</span><br><span> }</span><br><span> </span><br><span> </span><br><span>@@ -833,7 +851,7 @@</span><br><span> * \returns 0 in case of success; negative on error</span><br><span> */</span><br><span> int _osmo_fsm_inst_dispatch(struct osmo_fsm_inst *fi, uint32_t event, void *data,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span> struct osmo_fsm *fsm;</span><br><span> const struct osmo_fsm_state *fs;</span><br><span>@@ -847,11 +865,13 @@</span><br><span> }</span><br><span> </span><br><span> fsm = fi->fsm;</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENTSRC(fi, file, line, func, "event=%s", osmo_fsm_event_name(fsm, event));</span><br><span> </span><br><span> if (fi->proc.terminating) {</span><br><span> LOGPFSMSRC(fi, file, line,</span><br><span> "FSM instance already terminating, not dispatching event %s\n",</span><br><span> osmo_fsm_event_name(fsm, event));</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXTSRC(fi, file, line, func, "status=error");</span><br><span> return -EINVAL;</span><br><span> }</span><br><span> </span><br><span>@@ -863,6 +883,7 @@</span><br><span> </span><br><span> if (((1 << event) & fsm->allstate_event_mask) && fsm->allstate_action) {</span><br><span> fsm->allstate_action(fi, event, data);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXTSRC(fi, file, line, func, "status=ok");</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -870,12 +891,14 @@</span><br><span> LOGPFSMLSRC(fi, LOGL_ERROR, file, line,</span><br><span> "Event %s not permitted\n",</span><br><span> osmo_fsm_event_name(fsm, event));</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXTSRC(fi, file, line, func, "status=error");</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span> if (fs->action)</span><br><span> fs->action(fi, event, data);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXTSRC(fi, file, line, func, "status=ok");</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -897,7 +920,7 @@</span><br><span> */</span><br><span> void _osmo_fsm_inst_term(struct osmo_fsm_inst *fi,</span><br><span> enum osmo_fsm_term_cause cause, void *data,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span> struct osmo_fsm_inst *parent;</span><br><span> uint32_t parent_term_event = fi->proc.parent_term_event;</span><br><span>@@ -934,7 +957,7 @@</span><br><span> fi->fsm->pre_term(fi, cause);</span><br><span> </span><br><span> _osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL,</span><br><span style="color: hsl(0, 100%, 40%);">- file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ file, line, func);</span><br><span> </span><br><span> /* delete ourselves from the parent */</span><br><span> parent = fi->proc.parent;</span><br><span>@@ -962,7 +985,7 @@</span><br><span> /* indicate our termination to the parent */</span><br><span> if (parent && cause != OSMO_FSM_TERM_PARENT)</span><br><span> _osmo_fsm_inst_dispatch(parent, parent_term_event, data,</span><br><span style="color: hsl(0, 100%, 40%);">- file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ file, line, func);</span><br><span> </span><br><span> /* Newer, safe deallocation: free only after the parent_term_event was dispatched, to catch all termination</span><br><span> * cascades, and free all FSM instances at once. (If fsm_term_safely is enabled, depth will *always* be > 0</span><br><span>@@ -988,7 +1011,7 @@</span><br><span> void _osmo_fsm_inst_term_children(struct osmo_fsm_inst *fi,</span><br><span> enum osmo_fsm_term_cause cause,</span><br><span> void *data,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span> struct osmo_fsm_inst *first_child, *last_seen_first_child;</span><br><span> </span><br><span>@@ -1012,7 +1035,7 @@</span><br><span> </span><br><span> /* terminate child */</span><br><span> _osmo_fsm_inst_term(first_child, cause, data,</span><br><span style="color: hsl(0, 100%, 40%);">- file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ file, line, func);</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>@@ -1028,11 +1051,11 @@</span><br><span> */</span><br><span> void _osmo_fsm_inst_broadcast_children(struct osmo_fsm_inst *fi,</span><br><span> uint32_t event, void *data,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span> struct osmo_fsm_inst *child, *tmp;</span><br><span> llist_for_each_entry_safe(child, tmp, &fi->proc.children, proc.child) {</span><br><span style="color: hsl(0, 100%, 40%);">- _osmo_fsm_inst_dispatch(child, event, data, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ _osmo_fsm_inst_dispatch(child, event, data, file, line, func);</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/gb/gprs_ns2_vc_fsm.c b/src/gb/gprs_ns2_vc_fsm.c</span><br><span>index 7ee29a1..764445a 100644</span><br><span>--- a/src/gb/gprs_ns2_vc_fsm.c</span><br><span>+++ b/src/gb/gprs_ns2_vc_fsm.c</span><br><span>@@ -46,6 +46,7 @@</span><br><span> #include <osmocom/gprs/protocol/gsm_08_16.h></span><br><span> </span><br><span> #include "gprs_ns2_internal.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "osmocom/core/logging.h"</span><br><span> </span><br><span> #define S(x) (1 << (x))</span><br><span> </span><br><span>@@ -477,6 +478,7 @@</span><br><span> struct gprs_ns2_inst *nsi = ns_inst_from_fi(fi);</span><br><span> struct gprs_ns2_vc_priv *priv = fi->priv;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "nsei=%05u", priv->nsvc->nse->nsei);</span><br><span> switch (fi->state) {</span><br><span> case GPRS_NS2_ST_RESET:</span><br><span> if (priv->initiate_reset) {</span><br><span>@@ -521,6 +523,7 @@</span><br><span> }</span><br><span> break;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -533,8 +536,11 @@</span><br><span> struct osmo_gprs_ns2_prim nsp = {};</span><br><span> uint16_t bvci;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "nsei=%05u", priv->nsvc->nse->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (msgb_l2len(msg) < sizeof(*nsh) + 3) {</span><br><span> msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=error Message too small");</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span>@@ -549,6 +555,7 @@</span><br><span> nsp.bvci = bvci;</span><br><span> nsp.nsei = priv->nsvc->nse->nsei;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPATTR(DNS, "bvci=%05u", bvci);</span><br><span> /* 10.3.9 NS SDU Control Bits */</span><br><span> if (nsh->data[0] & 0x1)</span><br><span> nsp.u.unitdata.change = NS_ENDPOINT_REQUEST_CHANGE;</span><br><span>@@ -556,6 +563,7 @@</span><br><span> osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,</span><br><span> PRIM_OP_INDICATION, msg);</span><br><span> nsi->cb(&nsp.oph, nsi->cb_data);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> }</span><br><span> </span><br><span> static void ns2_vc_fsm_allstate_action(struct osmo_fsm_inst *fi,</span><br><span>@@ -566,6 +574,8 @@</span><br><span> struct gprs_ns2_inst *nsi = ns_inst_from_fi(fi);</span><br><span> struct msgb *msg = data;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "nsei=%05u", priv->nsvc->nse->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> switch (event) {</span><br><span> case GPRS_NS2_EV_RX_RESET:</span><br><span> if (priv->nsvc->mode != NS2_VC_MODE_BLOCKRESET)</span><br><span>@@ -607,6 +617,8 @@</span><br><span> /* 7.2.1: the BLOCKED_ACK might be lost */</span><br><span> if (priv->accept_unitdata) {</span><br><span> ns2_recv_unitdata(fi, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span>@@ -618,6 +630,7 @@</span><br><span> case GPRS_NS2_ST_ALIVE:</span><br><span> case GPRS_NS2_ST_UNBLOCKED:</span><br><span> ns2_recv_unitdata(fi, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span>@@ -628,6 +641,7 @@</span><br><span> /* Force the NSVC back to its initial state */</span><br><span> osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_UNCONFIGURED, 0, 0);</span><br><span> osmo_fsm_inst_dispatch(fi, GPRS_NS2_EV_REQ_START, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> return;</span><br><span> }</span><br><span> break;</span><br><span>@@ -646,6 +660,7 @@</span><br><span> osmo_fsm_inst_state_chg(fi, GPRS_NS2_ST_BLOCKED, nsi->timeout[NS_TOUT_TNS_BLOCK], 0);</span><br><span> break;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "");</span><br><span> }</span><br><span> </span><br><span> static void ns2_vc_fsm_clean(struct osmo_fsm_inst *fi,</span><br><span>@@ -694,6 +709,8 @@</span><br><span> if (!fi)</span><br><span> return fi;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "nsei=%05u", nsvc->nse->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> nsvc->fi = fi;</span><br><span> priv = fi->priv = talloc_zero(fi, struct gprs_ns2_vc_priv);</span><br><span> priv->nsvc = nsvc;</span><br><span>@@ -701,6 +718,8 @@</span><br><span> </span><br><span> osmo_timer_setup(&priv->alive.timer, alive_timeout_handler, fi);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return fi;</span><br><span> }</span><br><span> </span><br><span>@@ -752,6 +771,8 @@</span><br><span> uint8_t cause;</span><br><span> uint16_t nsei, nsvci;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMENT(fi, "nsei=%05u span.kind=server", nsvc->nse->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* TODO: 7.2: on UNBLOCK/BLOCK: check if NS-VCI is correct,</span><br><span> * if not answer STATUS with "NS-VC unknown" */</span><br><span> /* TODO: handle BLOCK/UNBLOCK/ALIVE with different VCI */</span><br><span>@@ -817,16 +838,20 @@</span><br><span> case NS_PDUT_UNITDATA:</span><br><span> /* UNITDATA have to free msg because it might send the msg layer upwards */</span><br><span> osmo_fsm_inst_dispatch(fi, GPRS_NS2_EV_RX_UNITDATA, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span> return 0;</span><br><span> default:</span><br><span> LOGPFSML(fi, LOGL_ERROR, "NSEI=%u Rx unknown NS PDU type %s\n", nsvc->nse->nsei,</span><br><span> get_value_string(gprs_ns_pdu_strings, nsh->pdu_type));</span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=error NSEI unknown");</span><br><span> return -EINVAL;</span><br><span> }</span><br><span> </span><br><span> out:</span><br><span> msgb_free(msg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ TRACEPFSMEXT(fi, "status=ok");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return rc;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/logging.c b/src/logging.c</span><br><span>index 60dba64..3462112 100644</span><br><span>--- a/src/logging.c</span><br><span>+++ b/src/logging.c</span><br><span>@@ -263,6 +263,12 @@</span><br><span> .enabled = 1, .loglevel = LOGL_NOTICE,</span><br><span> .color = "\033[38;5;59m",</span><br><span> },</span><br><span style="color: hsl(120, 100%, 40%);">+ [INT2IDX(DLTRACE)] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "DLTRACE",</span><br><span style="color: hsl(120, 100%, 40%);">+ .description = "Machine-parsable trace messages (for use with GSMTAP logging)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .enabled = 0, .loglevel = LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+ .color = "",</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span> };</span><br><span> </span><br><span> void assert_loginfo(const char *src)</span><br><span>diff --git a/src/tdef.c b/src/tdef.c</span><br><span>index 897a92f..3cd9696 100644</span><br><span>--- a/src/tdef.c</span><br><span>+++ b/src/tdef.c</span><br><span>@@ -332,29 +332,29 @@</span><br><span> int _osmo_tdef_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t state,</span><br><span> const struct osmo_tdef_state_timeout *timeouts_array,</span><br><span> const struct osmo_tdef *tdefs, unsigned long default_timeout,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *file, int line, const char *func)</span><br><span> {</span><br><span> const struct osmo_tdef_state_timeout *t = osmo_tdef_get_state_timeout(state, timeouts_array);</span><br><span> unsigned long val = 0;</span><br><span> </span><br><span> /* No timeout defined for this state? */</span><br><span> 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(120, 100%, 40%);">+ return _osmo_fsm_inst_state_chg(fi, state, 0, 0, file, line, func);</span><br><span> </span><br><span> if (t->T)</span><br><span> val = osmo_tdef_get(tdefs, t->T, OSMO_TDEF_S, default_timeout);</span><br><span> </span><br><span> if (t->keep_timer) {</span><br><span> if (t->T)</span><br><span style="color: hsl(0, 100%, 40%);">- return _osmo_fsm_inst_state_chg_keep_or_start_timer(fi, state, val, t->T, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _osmo_fsm_inst_state_chg_keep_or_start_timer(fi, state, val, t->T, file, line, func);</span><br><span> else</span><br><span style="color: hsl(0, 100%, 40%);">- return _osmo_fsm_inst_state_chg_keep_timer(fi, state, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _osmo_fsm_inst_state_chg_keep_timer(fi, state, file, line, func);</span><br><span> }</span><br><span> </span><br><span> /* val is always initialized here, because if t->keep_timer is false, t->T must be != 0.</span><br><span> * Otherwise osmo_tdef_get_state_timeout() would have returned NULL. */</span><br><span> OSMO_ASSERT(t->T);</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(120, 100%, 40%);">+ return _osmo_fsm_inst_state_chg(fi, state, val, t->T, file, line, func);</span><br><span> }</span><br><span> </span><br><span> const struct value_string osmo_tdef_unit_names[] = {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/22446">change 22446</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/c/libosmocore/+/22446"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I78945ab2bde7c93e9461dc446809f7cbd6493100 </div>
<div style="display:none"> Gerrit-Change-Number: 22446 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>