blob: 345be6676fe636a1f78e898e7d740d51b0e01ff3 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file fsm_vty.c
2 * Osmocom FSM introspection via VTY. */
3/*
4 * (C) 2016 by Harald Welte <laforge@gnumonks.org>
Harald Welte34193912017-01-07 11:49:55 +01005 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#include <stdlib.h>
24#include <string.h>
25
26#include "../../config.h"
27
28#include <osmocom/vty/command.h>
29#include <osmocom/vty/buffer.h>
30#include <osmocom/vty/vty.h>
31#include <osmocom/vty/telnet_interface.h>
32#include <osmocom/vty/misc.h>
33
34#include <osmocom/core/fsm.h>
35#include <osmocom/core/logging.h>
36#include <osmocom/core/linuxlist.h>
37
Harald Welte96e2a002017-06-12 21:44:18 +020038/*! \addtogroup fsm
39 * @{
Neels Hofmeyr87e45502017-06-20 00:17:59 +020040 * VTY interface for Osmocom FSM
Harald Welte96e2a002017-06-12 21:44:18 +020041 *
42 * This is code implementing generic VTY access to Osmocom FSMs from
43 * libosmocore. This means that any application can expose all state
44 * of all instances of all registered FSM classes by calling a single
45 * command during startup: \ref osmo_fsm_vty_add_cmds
46 */
47
Harald Welte34193912017-01-07 11:49:55 +010048/* we don't want to add this to a public header file; this is simply
49 * exported by libosmocore and used by libmsomvty but not for public
50 * consumption. */
51extern struct llist_head osmo_g_fsms;
52
Neels Hofmeyr87e45502017-06-20 00:17:59 +020053/*! Print information about a FSM [class] to the given VTY
Harald Welte34193912017-01-07 11:49:55 +010054 * \param vty The VTY to which to print
55 * \param[in] fsm The FSM class to print
56 */
57void vty_out_fsm(struct vty *vty, struct osmo_fsm *fsm)
58{
59 unsigned int i;
60 const struct value_string *evt_name;
61
62 vty_out(vty, "FSM Name: '%s', Log Subsys: '%s'%s", fsm->name,
63 log_category_name(fsm->log_subsys), VTY_NEWLINE);
64 /* list the events */
65 for (evt_name = fsm->event_names; evt_name->str != NULL; evt_name++) {
66 vty_out(vty, " Event %02u (0x%08x): '%s'%s", evt_name->value,
67 (1 << evt_name->value), evt_name->str, VTY_NEWLINE);
68 }
69 /* list the states */
70 vty_out(vty, " Number of States: %u%s", fsm->num_states, VTY_NEWLINE);
71 for (i = 0; i < fsm->num_states; i++) {
72 const struct osmo_fsm_state *state = &fsm->states[i];
73 vty_out(vty, " State %-20s InEvtMask: 0x%08x, OutStateMask: 0x%08x%s",
74 state->name, state->in_event_mask, state->out_state_mask,
75 VTY_NEWLINE);
76 }
77}
78
Neels Hofmeyr87e45502017-06-20 00:17:59 +020079/*! Print a FSM instance to the given VTY
Harald Welte34193912017-01-07 11:49:55 +010080 * \param vty The VTY to which to print
81 * \param[in] fsmi The FSM instance to print
82 */
83void vty_out_fsm_inst(struct vty *vty, struct osmo_fsm_inst *fsmi)
84{
85 struct osmo_fsm_inst *child;
86
87 vty_out(vty, "FSM Instance Name: '%s', ID: '%s'%s",
88 fsmi->name, fsmi->id, VTY_NEWLINE);
89 vty_out(vty, " Log-Level: '%s', State: '%s'%s",
90 log_level_str(fsmi->log_level),
91 osmo_fsm_state_name(fsmi->fsm, fsmi->state),
92 VTY_NEWLINE);
93 if (fsmi->T)
94 vty_out(vty, " Timer: %u%s", fsmi->T, VTY_NEWLINE);
95 if (fsmi->proc.parent) {
96 vty_out(vty, " Parent: '%s', Term-Event: '%s'%s",
97 fsmi->proc.parent->name,
98 osmo_fsm_event_name(fsmi->proc.parent->fsm,
99 fsmi->proc.parent_term_event),
100 VTY_NEWLINE);
101 }
102 llist_for_each_entry(child, &fsmi->proc.children, list) {
103 vty_out(vty, " Child: '%s'%s", child->name, VTY_NEWLINE);
104 }
105}
106
107#define SH_FSM_STR SHOW_STR "Show information about finite state machines\n"
108#define SH_FSMI_STR SHOW_STR "Show information about finite state machine instances\n"
109
110DEFUN(show_fsms, show_fsms_cmd,
111 "show fsm all",
112 SH_FSM_STR
113 "Display a list of all registered finite state machines\n")
114{
115 struct osmo_fsm *fsm;
116
117 llist_for_each_entry(fsm, &osmo_g_fsms, list)
118 vty_out_fsm(vty, fsm);
119
120 return CMD_SUCCESS;
121}
122
123DEFUN(show_fsm, show_fsm_cmd,
124 "show fsm NAME",
125 SH_FSM_STR
126 "Display information about a single named finite state machine\n")
127{
128 struct osmo_fsm *fsm;
129
130 fsm = osmo_fsm_find_by_name(argv[0]);
131 if (!fsm) {
132 vty_out(vty, "Error: FSM with name '%s' doesn't exist!%s",
133 argv[0], VTY_NEWLINE);
134 return CMD_WARNING;
135 }
136
137 vty_out_fsm(vty, fsm);
138
139 return CMD_SUCCESS;
140}
141
142DEFUN(show_fsm_insts, show_fsm_insts_cmd,
143 "show fsm-instances all",
144 SH_FSMI_STR
145 "Display a list of all FSM instances of all finite state machine")
146{
147 struct osmo_fsm *fsm;
148
149 llist_for_each_entry(fsm, &osmo_g_fsms, list) {
150 struct osmo_fsm_inst *fsmi;
151 llist_for_each_entry(fsmi, &fsm->instances, list)
152 vty_out_fsm_inst(vty, fsmi);
153 }
154
155 return CMD_SUCCESS;
156}
157
158DEFUN(show_fsm_inst, show_fsm_inst_cmd,
159 "show fsm-instances NAME",
160 SH_FSMI_STR
161 "Display a list of all FSM instances of the named finite state machine")
162{
163 struct osmo_fsm *fsm;
164 struct osmo_fsm_inst *fsmi;
165
166 fsm = osmo_fsm_find_by_name(argv[0]);
167 if (!fsm) {
168 vty_out(vty, "Error: FSM with name '%s' doesn't exist!%s",
169 argv[0], VTY_NEWLINE);
170 return CMD_WARNING;
171 }
172
173 llist_for_each_entry(fsmi, &fsm->instances, list)
174 vty_out_fsm_inst(vty, fsmi);
175
176 return CMD_SUCCESS;
177}
178
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200179/*! Install VTY commands for FSM introspection
Harald Welte34193912017-01-07 11:49:55 +0100180 * This installs a couple of VTY commands for introspection of FSM
181 * classes as well as FSM instances. Call this once from your
182 * application if you want to support those commands. */
183void osmo_fsm_vty_add_cmds(void)
184{
185 install_element_ve(&show_fsm_cmd);
186 install_element_ve(&show_fsms_cmd);
187 install_element_ve(&show_fsm_inst_cmd);
188 install_element_ve(&show_fsm_insts_cmd);
189}
Harald Welte96e2a002017-06-12 21:44:18 +0200190
191/*! @} */