\doxysection{src/core/fsm.c File Reference}
\label{fsm_8c}\index{src/core/fsm.c@{src/core/fsm.c}}


Osmocom generic Finite State Machine implementation.  


{\ttfamily \#include $<$errno.\+h$>$}\newline
{\ttfamily \#include $<$stdbool.\+h$>$}\newline
{\ttfamily \#include $<$string.\+h$>$}\newline
{\ttfamily \#include $<$inttypes.\+h$>$}\newline
{\ttfamily \#include \char`\"{}config.\+h\char`\"{}}\newline
{\ttfamily \#include $<$osmocom/core/fsm.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/talloc.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/logging.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/utils.\+h$>$}\newline
\doxysubsection*{Functions}
\begin{DoxyCompactItemize}
\item 
\textbf{ LLIST\+\_\+\+HEAD} (\textbf{ osmo\+\_\+g\+\_\+fsms})
\item 
static void \textbf{ fsm\+\_\+free\+\_\+or\+\_\+steal} (void $\ast$talloc\+\_\+object)
\begin{DoxyCompactList}\small\item\em Internal call to free an FSM instance, which redirects to the context set by \doxyref{osmo\+\_\+fsm\+\_\+set\+\_\+dealloc\+\_\+ctx()}{p.}{group__fsm_gaf031d280ac7d4fc8ac17e8560e5370a8} if any. \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+log\+\_\+addr} (bool log\+\_\+addr)
\begin{DoxyCompactList}\small\item\em specify if FSM instance addresses should be logged or not \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+log\+\_\+timeouts} (bool log\+\_\+timeouts)
\begin{DoxyCompactList}\small\item\em Enable or disable logging of timeout values for FSM instance state changes. \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+term\+\_\+safely} (bool term\+\_\+safely)
\begin{DoxyCompactList}\small\item\em Enable safer way to deallocate cascades of terminating FSM instances. \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+set\+\_\+dealloc\+\_\+ctx} (void $\ast$ctx)
\begin{DoxyCompactList}\small\item\em Instead of deallocating FSM instances, move them to the given talloc context. \end{DoxyCompactList}\item 
static void \textbf{ osmo\+\_\+fsm\+\_\+defer\+\_\+free} (void $\ast$talloc\+\_\+object)
\begin{DoxyCompactList}\small\item\em talloc\+\_\+free() the given object immediately, or once ongoing FSM terminations are done. \end{DoxyCompactList}\item 
struct \textbf{ osmo\+\_\+fsm} $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+find\+\_\+by\+\_\+name} (const char $\ast$\textbf{ name})
\item 
struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+find\+\_\+by\+\_\+name} (const struct \textbf{ osmo\+\_\+fsm} $\ast$fsm, const char $\ast$\textbf{ name})
\item 
struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+find\+\_\+by\+\_\+id} (const struct \textbf{ osmo\+\_\+fsm} $\ast$fsm, const char $\ast$id)
\item 
int \textbf{ osmo\+\_\+fsm\+\_\+register} (struct \textbf{ osmo\+\_\+fsm} $\ast$fsm)
\begin{DoxyCompactList}\small\item\em register a FSM with the core \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+unregister} (struct \textbf{ osmo\+\_\+fsm} $\ast$fsm)
\begin{DoxyCompactList}\small\item\em unregister a FSM from the core \end{DoxyCompactList}\item 
static void \textbf{ fsm\+\_\+tmr\+\_\+cb} (void $\ast$\textbf{ data})
\item 
int \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+update\+\_\+id} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, const char $\ast$id)
\begin{DoxyCompactList}\small\item\em Change id of the FSM instance. \end{DoxyCompactList}\item 
static void \textbf{ update\+\_\+name} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi)
\item 
int \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+update\+\_\+id\+\_\+f} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, const char $\ast$fmt,...)
\begin{DoxyCompactList}\small\item\em Change id of the FSM instance using a string format. \end{DoxyCompactList}\item 
int \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+update\+\_\+id\+\_\+f\+\_\+sanitize} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, char replace\+\_\+with, const char $\ast$fmt,...)
\begin{DoxyCompactList}\small\item\em Change id of the FSM instance using a string format, and ensuring a valid id. \end{DoxyCompactList}\item 
struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+alloc} (struct \textbf{ osmo\+\_\+fsm} $\ast$fsm, void $\ast$ctx, void $\ast$priv, int log\+\_\+level, const char $\ast$id)
\begin{DoxyCompactList}\small\item\em allocate a new instance of a specified FSM \end{DoxyCompactList}\item 
struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+alloc\+\_\+child} (struct \textbf{ osmo\+\_\+fsm} $\ast$fsm, struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$parent, uint32\+\_\+t parent\+\_\+term\+\_\+event)
\begin{DoxyCompactList}\small\item\em allocate a new instance of a specified FSM as child of other FSM instance \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+unlink\+\_\+parent} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, void $\ast$ctx)
\begin{DoxyCompactList}\small\item\em unlink child FSM from its parent FSM. \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+change\+\_\+parent} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$new\+\_\+parent, uint32\+\_\+t new\+\_\+parent\+\_\+term\+\_\+event)
\begin{DoxyCompactList}\small\item\em change parent instance of an FSM. \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+free} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi)
\begin{DoxyCompactList}\small\item\em delete a given instance of a FSM \end{DoxyCompactList}\item 
const char $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+event\+\_\+name} (const struct \textbf{ osmo\+\_\+fsm} $\ast$fsm, uint32\+\_\+t \textbf{ event})
\begin{DoxyCompactList}\small\item\em get human-\/readable name of FSM event \end{DoxyCompactList}\item 
const char $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+inst\+\_\+name} (const struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi)
\begin{DoxyCompactList}\small\item\em get human-\/readable name of FSM instance \end{DoxyCompactList}\item 
const char $\ast$ \textbf{ osmo\+\_\+fsm\+\_\+state\+\_\+name} (const struct \textbf{ osmo\+\_\+fsm} $\ast$fsm, uint32\+\_\+t state)
\begin{DoxyCompactList}\small\item\em get human-\/readable name of FSM state \end{DoxyCompactList}\item 
static int \textbf{ state\+\_\+chg} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t new\+\_\+state, bool keep\+\_\+timer, unsigned long timeout\+\_\+ms, int T, const char $\ast$\textbf{ file}, int line)
\item 
int \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+state\+\_\+chg} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t new\+\_\+state, unsigned long timeout\+\_\+secs, int T, const char $\ast$\textbf{ file}, int line)
\begin{DoxyCompactList}\small\item\em perform a state change of the given FSM instance \end{DoxyCompactList}\item 
int \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+state\+\_\+chg\+\_\+ms} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t new\+\_\+state, unsigned long timeout\+\_\+ms, int T, const char $\ast$\textbf{ file}, int line)
\item 
int \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+state\+\_\+chg\+\_\+keep\+\_\+timer} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t new\+\_\+state, const char $\ast$\textbf{ file}, int line)
\begin{DoxyCompactList}\small\item\em perform a state change while keeping the current timer running. \end{DoxyCompactList}\item 
int \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+state\+\_\+chg\+\_\+keep\+\_\+or\+\_\+start\+\_\+timer} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t new\+\_\+state, unsigned long timeout\+\_\+secs, int T, const char $\ast$\textbf{ file}, int line)
\begin{DoxyCompactList}\small\item\em perform a state change while keeping the current timer if running, or starting a timer otherwise. \end{DoxyCompactList}\item 
int \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+state\+\_\+chg\+\_\+keep\+\_\+or\+\_\+start\+\_\+timer\+\_\+ms} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t new\+\_\+state, unsigned long timeout\+\_\+ms, int T, const char $\ast$\textbf{ file}, int line)
\item 
int \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+dispatch} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t \textbf{ event}, void $\ast$\textbf{ data}, const char $\ast$\textbf{ file}, int line)
\begin{DoxyCompactList}\small\item\em dispatch an event to an osmocom finite state machine instance \end{DoxyCompactList}\item 
void \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+term} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, enum \textbf{ osmo\+\_\+fsm\+\_\+term\+\_\+cause} \textbf{ cause}, void $\ast$\textbf{ data}, const char $\ast$\textbf{ file}, int line)
\begin{DoxyCompactList}\small\item\em Terminate FSM instance with given cause. \end{DoxyCompactList}\item 
void \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+term\+\_\+children} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, enum \textbf{ osmo\+\_\+fsm\+\_\+term\+\_\+cause} \textbf{ cause}, void $\ast$\textbf{ data}, const char $\ast$\textbf{ file}, int line)
\begin{DoxyCompactList}\small\item\em Terminate all child FSM instances of an FSM instance. \end{DoxyCompactList}\item 
void \textbf{ \+\_\+osmo\+\_\+fsm\+\_\+inst\+\_\+broadcast\+\_\+children} (struct \textbf{ osmo\+\_\+fsm\+\_\+inst} $\ast$fi, uint32\+\_\+t \textbf{ event}, void $\ast$\textbf{ data}, const char $\ast$\textbf{ file}, int line)
\begin{DoxyCompactList}\small\item\em Broadcast an event to all the FSMs children. \end{DoxyCompactList}\end{DoxyCompactItemize}
\doxysubsection*{Variables}
\begin{DoxyCompactItemize}
\item 
static bool \textbf{ fsm\+\_\+log\+\_\+addr} = true
\item 
static bool \textbf{ fsm\+\_\+log\+\_\+timeouts} = false
\item 
static bool \textbf{ fsm\+\_\+term\+\_\+safely\+\_\+enabled} = false
\begin{DoxyCompactList}\small\item\em See \doxyref{osmo\+\_\+fsm\+\_\+term\+\_\+safely()}{p.}{group__fsm_ga7ae199b946d722bc789b1c59f7c3aa15}. \end{DoxyCompactList}\item 
\begin{tabbing}
xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=\kill
struct \{\\
\>struct \textbf{ osmo\_fsm\_inst} $\ast$ \textbf{ root\_fi}\\
\>\>{\em The first FSM instance that invoked \doxyref{osmo\_fsm\_inst\_term()}{p.}{group__fsm_ga22397fdc69a4f1c303bb0b2694d5f2aa} in the current cascade. }\\
\>unsigned int \textbf{ depth}\\
\>\>{\em 2 if a secondary FSM terminates, 3 if a secondary FSM causes a tertiary FSM to terminate, and so on. }\\
\>void $\ast$ \textbf{ collect\_ctx}\\
\>\>{\em Talloc context to collect all deferred deallocations (FSM instances, and talloc objects if any). }\\
\>void $\ast$ \textbf{ fsm\_dealloc\_ctx}\\
\>\>{\em See \doxyref{osmo\_fsm\_set\_dealloc\_ctx()}{p.}{group__fsm_gaf031d280ac7d4fc8ac17e8560e5370a8} }\\
\} \textbf{ fsm\_term\_safely}\\

\end{tabbing}\begin{DoxyCompactList}\small\item\em Internal state for FSM instance termination cascades. \end{DoxyCompactList}\item 
const struct \textbf{ value\+\_\+string} \textbf{ osmo\+\_\+fsm\+\_\+term\+\_\+cause\+\_\+names} [$\,$]
\end{DoxyCompactItemize}


\doxysubsection{Detailed Description}
Osmocom generic Finite State Machine implementation. 



\doxysubsection{Variable Documentation}
\mbox{\label{fsm_8c_afd962301701a4aaba800ea611d5161e6}} 
\index{fsm.c@{fsm.c}!collect\_ctx@{collect\_ctx}}
\index{collect\_ctx@{collect\_ctx}!fsm.c@{fsm.c}}
\doxysubsubsection{collect\_ctx}
{\footnotesize\ttfamily void$\ast$ collect\+\_\+ctx}



Talloc context to collect all deferred deallocations (FSM instances, and talloc objects if any). 

\mbox{\label{fsm_8c_a5081a26baa914156df8541b03d09492e}} 
\index{fsm.c@{fsm.c}!depth@{depth}}
\index{depth@{depth}!fsm.c@{fsm.c}}
\doxysubsubsection{depth}
{\footnotesize\ttfamily unsigned int depth}



2 if a secondary FSM terminates, 3 if a secondary FSM causes a tertiary FSM to terminate, and so on. 

\mbox{\label{fsm_8c_a5f36d9c24f565ba616d29d9603c285fa}} 
\index{fsm.c@{fsm.c}!fsm\_dealloc\_ctx@{fsm\_dealloc\_ctx}}
\index{fsm\_dealloc\_ctx@{fsm\_dealloc\_ctx}!fsm.c@{fsm.c}}
\doxysubsubsection{fsm\_dealloc\_ctx}
{\footnotesize\ttfamily void$\ast$ fsm\+\_\+dealloc\+\_\+ctx}



See \doxyref{osmo\+\_\+fsm\+\_\+set\+\_\+dealloc\+\_\+ctx()}{p.}{group__fsm_gaf031d280ac7d4fc8ac17e8560e5370a8} 

\mbox{\label{fsm_8c_ac87816006076bba6d6da5fd064c802eb}} 
\index{fsm.c@{fsm.c}!root\_fi@{root\_fi}}
\index{root\_fi@{root\_fi}!fsm.c@{fsm.c}}
\doxysubsubsection{root\_fi}
{\footnotesize\ttfamily struct \textbf{ osmo\+\_\+fsm\+\_\+inst}$\ast$ root\+\_\+fi}



The first FSM instance that invoked \doxyref{osmo\+\_\+fsm\+\_\+inst\+\_\+term()}{p.}{group__fsm_ga22397fdc69a4f1c303bb0b2694d5f2aa} in the current cascade. 

