libosmocore 1.13.1.1-afb4 Osmocom core library

fsm.h
Go to the documentation of this file.
1
5#pragma once
6
7#include <stdint.h>
8#include <stdbool.h>
9
10#include <osmocom/core/linuxlist.h>
11#include <osmocom/core/timer.h>
12#include <osmocom/core/utils.h>
13#include <osmocom/core/logging.h>
14
19 struct osmo_fsm_inst;
20
21 enum osmo_fsm_term_cause {
23 OSMO_FSM_TERM_PARENT,
25 OSMO_FSM_TERM_REQUEST,
27 OSMO_FSM_TERM_REGULAR,
29 OSMO_FSM_TERM_ERROR,
31 OSMO_FSM_TERM_TIMEOUT,
32};
33
34 extern const struct value_string osmo_fsm_term_cause_names[];
35 static inline const char *osmo_fsm_term_cause_name(enum osmo_fsm_term_cause cause)
36{
37 return get_value_string(osmo_fsm_term_cause_names, cause);
38}
39
40
42 struct osmo_fsm_state {
44 uint32_t in_event_mask;
46 uint32_t out_state_mask;
48 const char *name;
50 void (*action)(struct osmo_fsm_inst *fi, uint32_t event, void *data);
52 void (*onenter)(struct osmo_fsm_inst *fi, uint32_t prev_state);
54 void (*onleave)(struct osmo_fsm_inst *fi, uint32_t next_state);
55};
56
58 struct osmo_fsm {
60 struct llist_head list;
62 struct llist_head instances;
64 const char *name;
66 const struct osmo_fsm_state *states;
68 unsigned int num_states;
70 uint32_t allstate_event_mask;
72 void (*allstate_action)(struct osmo_fsm_inst *fi, uint32_t event, void *data);
74 void (*cleanup)(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause);
77 int (*timer_cb)(struct osmo_fsm_inst *fi);
79 int log_subsys;
81 const struct value_string *event_names;
83 void (*pre_term)(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause);
84};
85
87 struct osmo_fsm_inst {
89 struct llist_head list;
91 struct osmo_fsm *fsm;
93 const char *id;
95 const char *name;
97 void *priv;
99 int log_level;
101 uint32_t state;
102
104 int T;
106 struct osmo_timer_list timer;
107
109 struct {
111 struct osmo_fsm_inst *parent;
113 uint32_t parent_term_event;
115 struct llist_head children;
117 struct llist_head child;
119 bool terminating;
120 } proc;
121};
122
123 void osmo_fsm_log_addr(bool log_addr);
124 void osmo_fsm_log_timeouts(bool log_timeouts);
125 void osmo_fsm_term_safely(bool term_safely);
126 void osmo_fsm_set_dealloc_ctx(void *ctx);
127
135#define LOGPFSMSL(fi, subsys, level, fmt, args...) \
136 LOGPFSMSLSRC(fi, subsys, level, __FILE__, __LINE__, fmt, ## args)
137
148#define LOGPFSMSLSRC(fi, subsys, level, caller_file, caller_line, fmt, args...) \
149 LOGPSRC(subsys, level, \
150 caller_file, caller_line, \
151 "%s{%s}: " fmt, \
152 osmo_fsm_inst_name(fi), \
153 (fi) ? osmo_fsm_state_name((fi)->fsm, (fi)->state) : "fi=NULL", ## args)
154
155
162#define LOGPFSML(fi, level, fmt, args...) \
163 LOGPFSMLSRC(fi, level, __FILE__, __LINE__, fmt, ## args)
164
174#define LOGPFSMLSRC(fi, level, caller_file, caller_line, fmt, args...) \
175 LOGPFSMSLSRC(fi, (fi) ? (fi)->fsm->log_subsys : DLGLOBAL, level, \
176 caller_file, caller_line, fmt, ## args)
177
185#define LOGPFSM(fi, fmt, args...) \
186 LOGPFSML(fi, (fi) ? (fi)->log_level : LOGL_ERROR, fmt, ## args)
187
197#define LOGPFSMSRC(fi, caller_file, caller_line, fmt, args...) \
198 LOGPFSMLSRC(fi, (fi) ? (fi)->log_level : LOGL_ERROR, \
199 caller_file, caller_line, \
200 fmt, ## args)
201
202#define OSMO_T_FMT "%c%u"
203#define OSMO_T_FMT_ARGS(T) ((T) >= 0 ? 'T' : 'X'), ((T) >= 0 ? (T) : -(T))
204
205 int osmo_fsm_register(struct osmo_fsm *fsm);
206 void osmo_fsm_unregister(struct osmo_fsm *fsm);
207 struct osmo_fsm *osmo_fsm_find_by_name(const char *name);
208 struct osmo_fsm_inst *osmo_fsm_inst_find_by_name(const struct osmo_fsm *fsm,
209 const char *name);
210 struct osmo_fsm_inst *osmo_fsm_inst_find_by_id(const struct osmo_fsm *fsm,
211 const char *id);
212 struct osmo_fsm_inst *osmo_fsm_inst_alloc(struct osmo_fsm *fsm, void *ctx, void *priv,
213 int log_level, const char *id);
214 struct osmo_fsm_inst *osmo_fsm_inst_alloc_child(struct osmo_fsm *fsm,
215 struct osmo_fsm_inst *parent,
216 uint32_t parent_term_event);
217 void osmo_fsm_inst_unlink_parent(struct osmo_fsm_inst *fi, void *ctx);
218 void osmo_fsm_inst_change_parent(struct osmo_fsm_inst *fi,
219 struct osmo_fsm_inst *new_parent,
220 uint32_t new_parent_term_event);
221 void osmo_fsm_inst_free(struct osmo_fsm_inst *fi);
222
223 int osmo_fsm_inst_update_id(struct osmo_fsm_inst *fi, const char *id);
224 int osmo_fsm_inst_update_id_f(struct osmo_fsm_inst *fi, const char *fmt, ...);
225 int osmo_fsm_inst_update_id_f_sanitize(struct osmo_fsm_inst *fi, char replace_with, const char *fmt, ...);
226
227 const char *osmo_fsm_event_name(const struct osmo_fsm *fsm, uint32_t event);
228 const char *osmo_fsm_inst_name(const struct osmo_fsm_inst *fi);
229 const char *osmo_fsm_state_name(const struct osmo_fsm *fsm, uint32_t state);
230
232 static inline const char *osmo_fsm_inst_state_name(struct osmo_fsm_inst *fi)
233{ return fi ? osmo_fsm_state_name(fi->fsm, fi->state) : "NULL"; }
234
241#define osmo_fsm_inst_state_chg(fi, new_state, timeout_secs, T) \
242 _osmo_fsm_inst_state_chg(fi, new_state, timeout_secs, T, \
243 __FILE__, __LINE__)
244 int _osmo_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t new_state,
245 unsigned long timeout_secs, int T,
246 const char *file, int line);
247
248#define osmo_fsm_inst_state_chg_ms(fi, new_state, timeout_ms, T) \
249 _osmo_fsm_inst_state_chg_ms(fi, new_state, timeout_ms, T, \
250 __FILE__, __LINE__)
251 int _osmo_fsm_inst_state_chg_ms(struct osmo_fsm_inst *fi, uint32_t new_state,
252 unsigned long timeout_ms, int T,
253 const char *file, int line);
254
264#define osmo_fsm_inst_state_chg_keep_timer(fi, new_state) \
265 _osmo_fsm_inst_state_chg_keep_timer(fi, new_state, \
266 __FILE__, __LINE__)
267 int _osmo_fsm_inst_state_chg_keep_timer(struct osmo_fsm_inst *fi, uint32_t new_state,
268 const char *file, int line);
269
278#define osmo_fsm_inst_state_chg_keep_or_start_timer(fi, new_state, timeout_secs, T) \
279 _osmo_fsm_inst_state_chg_keep_or_start_timer(fi, new_state, timeout_secs, T, \
280 __FILE__, __LINE__)
281 int _osmo_fsm_inst_state_chg_keep_or_start_timer(struct osmo_fsm_inst *fi, uint32_t new_state,
282 unsigned long timeout_secs, int T,
283 const char *file, int line);
284
285#define osmo_fsm_inst_state_chg_keep_or_start_timer_ms(fi, new_state, timeout_ms, T) \
286 _osmo_fsm_inst_state_chg_keep_or_start_timer_ms(fi, new_state, timeout_ms, T, \
287 __FILE__, __LINE__)
288 int _osmo_fsm_inst_state_chg_keep_or_start_timer_ms(struct osmo_fsm_inst *fi, uint32_t new_state,
289 unsigned long timeout_ms, int T,
290 const char *file, int line);
291
292
299#define osmo_fsm_inst_dispatch(fi, event, data) \
300 _osmo_fsm_inst_dispatch(fi, event, data, __FILE__, __LINE__)
301 int _osmo_fsm_inst_dispatch(struct osmo_fsm_inst *fi, uint32_t event, void *data,
302 const char *file, int line);
303
310#define osmo_fsm_inst_term(fi, cause, data) \
311 _osmo_fsm_inst_term(fi, cause, data, __FILE__, __LINE__)
312 void _osmo_fsm_inst_term(struct osmo_fsm_inst *fi,
313 enum osmo_fsm_term_cause cause, void *data,
314 const char *file, int line);
315
322#define osmo_fsm_inst_term_children(fi, cause, data) \
323 _osmo_fsm_inst_term_children(fi, cause, data, __FILE__, __LINE__)
324 void _osmo_fsm_inst_term_children(struct osmo_fsm_inst *fi,
325 enum osmo_fsm_term_cause cause,
326 void *data,
327 const char *file, int line);
328
335#define osmo_fsm_inst_broadcast_children(fi, cause, data) \
336 _osmo_fsm_inst_broadcast_children(fi, cause, data, __FILE__, __LINE__)
337 void _osmo_fsm_inst_broadcast_children(struct osmo_fsm_inst *fi, uint32_t event,
338 void *data, const char *file, int line);
339
name
const char * name
file
write Write running configuration to or terminal n Write configuration to the file(same as write file)\n") ALIAS(config_write_file
_osmo_fsm_inst_state_chg_ms
int _osmo_fsm_inst_state_chg_ms(struct osmo_fsm_inst *fi, uint32_t new_state, unsigned long timeout_ms, int T, const char *file, int line)
Definition: fsm.c:749
osmo_fsm_inst_update_id_f_sanitize
int osmo_fsm_inst_update_id_f_sanitize(struct osmo_fsm_inst *fi, char replace_with, const char *fmt,...)
Change id of the FSM instance using a string format, and ensuring a valid id.
Definition: fsm.c:410
osmo_fsm_inst_name
const char * osmo_fsm_inst_name(const struct osmo_fsm_inst *fi)
get human-readable name of FSM instance
Definition: fsm.c:594
_osmo_fsm_inst_state_chg_keep_or_start_timer
int _osmo_fsm_inst_state_chg_keep_or_start_timer(struct osmo_fsm_inst *fi, uint32_t new_state, unsigned long timeout_secs, int T, const char *file, int line)
perform a state change while keeping the current timer if running, or starting a timer otherwise.
Definition: fsm.c:803
osmo_fsm_term_cause
osmo_fsm_term_cause
Definition: fsm.h:21
osmo_fsm_find_by_name
struct osmo_fsm * osmo_fsm_find_by_name(const char *name)
Definition: fsm.c:236
osmo_fsm_event_name
const char * osmo_fsm_event_name(const struct osmo_fsm *fsm, uint32_t event)
get human-readable name of FSM event
Definition: fsm.c:580
_osmo_fsm_inst_term_children
void _osmo_fsm_inst_term_children(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause, void *data, const char *file, int line)
Terminate all child FSM instances of an FSM instance.
Definition: fsm.c:987
_osmo_fsm_inst_state_chg_keep_or_start_timer_ms
int _osmo_fsm_inst_state_chg_keep_or_start_timer_ms(struct osmo_fsm_inst *fi, uint32_t new_state, unsigned long timeout_ms, int T, const char *file, int line)
Definition: fsm.c:809
osmo_fsm_unregister
void osmo_fsm_unregister(struct osmo_fsm *fsm)
unregister a FSM from the core
Definition: fsm.c:306
osmo_fsm_inst_update_id_f
int osmo_fsm_inst_update_id_f(struct osmo_fsm_inst *fi, const char *fmt,...)
Change id of the FSM instance using a string format.
Definition: fsm.c:373
osmo_fsm_inst_change_parent
void osmo_fsm_inst_change_parent(struct osmo_fsm_inst *fi, struct osmo_fsm_inst *new_parent, uint32_t new_parent_term_event)
change parent instance of an FSM.
Definition: fsm.c:518
osmo_fsm_register
int osmo_fsm_register(struct osmo_fsm *fsm)
register a FSM with the core
Definition: fsm.c:283
osmo_fsm_term_cause_names
const struct value_string osmo_fsm_term_cause_names[]
Definition: fsm.c:1038
osmo_fsm_inst_free
void osmo_fsm_inst_free(struct osmo_fsm_inst *fi)
delete a given instance of a FSM
Definition: fsm.c:537
_osmo_fsm_inst_broadcast_children
void _osmo_fsm_inst_broadcast_children(struct osmo_fsm_inst *fi, uint32_t event, void *data, const char *file, int line)
Broadcast an event to all the FSMs children.
Definition: fsm.c:1028
_osmo_fsm_inst_dispatch
int _osmo_fsm_inst_dispatch(struct osmo_fsm_inst *fi, uint32_t event, void *data, const char *file, int line)
dispatch an event to an osmocom finite state machine instance
Definition: fsm.c:834
_osmo_fsm_inst_state_chg
int _osmo_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t new_state, unsigned long timeout_secs, int T, const char *file, int line)
perform a state change of the given FSM instance
Definition: fsm.c:743
osmo_fsm_term_safely
void osmo_fsm_term_safely(bool term_safely)
Enable safer way to deallocate cascades of terminating FSM instances.
Definition: fsm.c:169
osmo_fsm_log_addr
void osmo_fsm_log_addr(bool log_addr)
specify if FSM instance addresses should be logged or not
Definition: fsm.c:123
osmo_fsm_inst_unlink_parent
void osmo_fsm_inst_unlink_parent(struct osmo_fsm_inst *fi, void *ctx)
unlink child FSM from its parent FSM.
Definition: fsm.c:501
osmo_fsm_inst_alloc_child
struct osmo_fsm_inst * osmo_fsm_inst_alloc_child(struct osmo_fsm *fsm, struct osmo_fsm_inst *parent, uint32_t parent_term_event)
allocate a new instance of a specified FSM as child of other FSM instance
Definition: fsm.c:473
osmo_fsm_term_cause_name
static const char * osmo_fsm_term_cause_name(enum osmo_fsm_term_cause cause)
Definition: fsm.h:35
_osmo_fsm_inst_term
void _osmo_fsm_inst_term(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause, void *data, const char *file, int line)
Terminate FSM instance with given cause.
Definition: fsm.c:897
osmo_fsm_log_timeouts
void osmo_fsm_log_timeouts(bool log_timeouts)
Enable or disable logging of timeout values for FSM instance state changes.
Definition: fsm.c:143
_osmo_fsm_inst_state_chg_keep_timer
int _osmo_fsm_inst_state_chg_keep_timer(struct osmo_fsm_inst *fi, uint32_t new_state, const char *file, int line)
perform a state change while keeping the current timer running.
Definition: fsm.c:775
osmo_fsm_inst_alloc
struct osmo_fsm_inst * osmo_fsm_inst_alloc(struct osmo_fsm *fsm, void *ctx, void *priv, int log_level, const char *id)
allocate a new instance of a specified FSM
Definition: fsm.c:438
osmo_fsm_inst_update_id
int osmo_fsm_inst_update_id(struct osmo_fsm_inst *fi, const char *id)
Change id of the FSM instance.
Definition: fsm.c:341
osmo_fsm_state_name
const char * osmo_fsm_state_name(const struct osmo_fsm *fsm, uint32_t state)
get human-readable name of FSM state
Definition: fsm.c:610
osmo_fsm_set_dealloc_ctx
void osmo_fsm_set_dealloc_ctx(void *ctx)
Instead of deallocating FSM instances, move them to the given talloc context.
Definition: fsm.c:194
osmo_fsm_inst_state_name
static const char * osmo_fsm_inst_state_name(struct osmo_fsm_inst *fi)
return the name of the state the FSM instance is currently in.
Definition: fsm.h:232
osmo_fsm_inst_find_by_id
struct osmo_fsm_inst * osmo_fsm_inst_find_by_id(const struct osmo_fsm *fsm, const char *id)
Definition: fsm.c:263
osmo_fsm_inst_find_by_name
struct osmo_fsm_inst * osmo_fsm_inst_find_by_name(const struct osmo_fsm *fsm, const char *name)
Definition: fsm.c:246
OSMO_FSM_TERM_REQUEST
@ OSMO_FSM_TERM_REQUEST
terminate on explicit user request
Definition: fsm.h:25
OSMO_FSM_TERM_ERROR
@ OSMO_FSM_TERM_ERROR
erroneous termination of process
Definition: fsm.h:29
OSMO_FSM_TERM_TIMEOUT
@ OSMO_FSM_TERM_TIMEOUT
termination due to time-out
Definition: fsm.h:31
OSMO_FSM_TERM_REGULAR
@ OSMO_FSM_TERM_REGULAR
regular termination of process
Definition: fsm.h:27
OSMO_FSM_TERM_PARENT
@ OSMO_FSM_TERM_PARENT
terminate because parent terminated
Definition: fsm.h:23
data
uint8_t data[0]
get_value_string
const char * get_value_string(const struct value_string *vs, uint32_t val)
get human-readable string for given value
Definition: utils.c:63
event
event
cause
uint8_t cause
linuxlist.h
Simple doubly linked list implementation.
logging.h
llist_head
(double) linked list header structure
Definition: linuxlist.h:46
osmo_fsm_inst
a single instanceof an osmocom finite state machine
Definition: fsm.h:87
osmo_fsm_inst::parent
struct osmo_fsm_inst * parent
the parent FSM that has created us
Definition: fsm.h:111
osmo_fsm_inst::fsm
struct osmo_fsm * fsm
back-pointer to the FSM of which we are an instance
Definition: fsm.h:91
osmo_fsm_inst::name
const char * name
human readable fully-qualified name
Definition: fsm.h:95
osmo_fsm_inst::log_level
int log_level
logging level for this FSM
Definition: fsm.h:99
osmo_fsm_inst::priv
void * priv
some private data of this instance
Definition: fsm.h:97
osmo_fsm_inst::id
const char * id
human readable identifier
Definition: fsm.h:93
osmo_fsm_inst::state
uint32_t state
current state of the FSM
Definition: fsm.h:101
osmo_fsm_inst::child
struct llist_head child
llist_head linked to parent->proc.children
Definition: fsm.h:117
osmo_fsm_inst::proc
struct osmo_fsm_inst::@0 proc
support for fsm-based procedures
osmo_fsm_inst::list
struct llist_head list
member in the fsm->instances list
Definition: fsm.h:89
osmo_fsm_inst::T
int T
timer number for states with time-out
Definition: fsm.h:104
osmo_fsm_inst::terminating
bool terminating
Indicator whether osmo_fsm_inst_term() was already invoked on this instance.
Definition: fsm.h:119
osmo_fsm_inst::parent_term_event
uint32_t parent_term_event
the event we should send upon termination
Definition: fsm.h:113
osmo_fsm_inst::children
struct llist_head children
a list of children processes
Definition: fsm.h:115
osmo_fsm_inst::timer
struct osmo_timer_list timer
timer back-end for states with time-out
Definition: fsm.h:106
osmo_fsm_state
description of a rule in the FSM
Definition: fsm.h:42
osmo_fsm_state::onenter
void(* onenter)(struct osmo_fsm_inst *fi, uint32_t prev_state)
function to be called just after entering the state
Definition: fsm.h:52
osmo_fsm_state::out_state_mask
uint32_t out_state_mask
bit-mask to which other states this state may transiton
Definition: fsm.h:46
osmo_fsm_state::name
const char * name
human-readable name of this state
Definition: fsm.h:48
osmo_fsm_state::in_event_mask
uint32_t in_event_mask
bit-mask of permitted input events for this state
Definition: fsm.h:44
osmo_fsm_state::action
void(* action)(struct osmo_fsm_inst *fi, uint32_t event, void *data)
function to be called for events arriving in this state
Definition: fsm.h:50
osmo_fsm_state::onleave
void(* onleave)(struct osmo_fsm_inst *fi, uint32_t next_state)
function to be called just before leaving the state
Definition: fsm.h:54
osmo_fsm
a description of an osmocom finite state machine
Definition: fsm.h:58
osmo_fsm::allstate_event_mask
uint32_t allstate_event_mask
bit-mask of events permitted in all states
Definition: fsm.h:70
osmo_fsm::allstate_action
void(* allstate_action)(struct osmo_fsm_inst *fi, uint32_t event, void *data)
function pointer to be called for allstate events
Definition: fsm.h:72
osmo_fsm::timer_cb
int(* timer_cb)(struct osmo_fsm_inst *fi)
timer call-back for states with time-out.
Definition: fsm.h:77
osmo_fsm::num_states
unsigned int num_states
number of entries in states
Definition: fsm.h:68
osmo_fsm::log_subsys
int log_subsys
logging sub-system for this FSM
Definition: fsm.h:79
osmo_fsm::cleanup
void(* cleanup)(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
clean-up function, called during termination
Definition: fsm.h:74
osmo_fsm::name
const char * name
human readable name
Definition: fsm.h:64
osmo_fsm::event_names
const struct value_string * event_names
human-readable names of events
Definition: fsm.h:81
osmo_fsm::list
struct llist_head list
global list
Definition: fsm.h:60
osmo_fsm::pre_term
void(* pre_term)(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
graceful exit function, called at the beginning of termination
Definition: fsm.h:83
osmo_fsm::instances
struct llist_head instances
list of instances of this FSM
Definition: fsm.h:62
osmo_fsm::states
const struct osmo_fsm_state * states
table of state transition rules
Definition: fsm.h:66
osmo_timer_list
A structure representing a single instance of a timer.
Definition: timer.h:52
value_string
A mapping between human-readable string and numeric value.
Definition: utils.h:51
timer.h
Osmocom timer handling routines.
utils.h