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