blob: 689aec7cd7219f1b2371fc748284eec632cf3b8e [file] [log] [blame]
Harald Welte39cfbf42016-07-28 09:04:11 +02001
2#include <osmocom/abis/e1_input.h>
3#include <osmocom/vty/command.h>
4#include <osmocom/vty/vty.h>
5
6#include "recorder.h"
7
8#define LINE_STR "Configure Recording for given Line\nE1/T1 Line Number\n"
9
10DEFUN(cfg_recorder, cfg_recorder_cmd,
11 "recorder",
12 "Configuration of E1 Recorder\n")
13{
14 vty->node = RECORDER_NODE;
15 return CMD_SUCCESS;
16}
17
Harald Welteb7e40232016-07-29 14:26:50 +020018static const struct e1inp_line_ops dummy_e1i_line_ops = {
19 .sign_link_up = NULL,
20 .sign_link_down = NULL,
21 .sign_link = NULL,
22};
23
Harald Welte39cfbf42016-07-28 09:04:11 +020024DEFUN(cfg_rec_line_ts_mode, cfg_rec_line_ts_mode_cmd,
Harald Welte13351132016-10-17 22:13:36 +020025 "line <0-255> ts <1-31> mode (none|hdlc|trau|raw)",
Harald Welte39cfbf42016-07-28 09:04:11 +020026 LINE_STR
27 "E1/T1 Timeslot Number\n"
28 "E1/T1 Timeslot Number\n"
29 "Recording Mode\n"
30 "No recording\n"
31 "Signalling Data (HDLC)\n"
32 "TRAU Frames\n"
33 "Raw Data\n")
34{
35 int line_nr = atoi(argv[0]);
36 int ts_nr = atoi(argv[1]);
37 int mode = get_string_value(e1inp_ts_type_names, argv[2]);
38 struct e1inp_line *line;
39 struct e1inp_ts *ts;
40
41 if (mode < 0) {
42 vty_out(vty, "Cannot parse mode %s%s", argv[2], VTY_NEWLINE);
43 return CMD_WARNING;
44 }
45
46 line = e1inp_line_find(line_nr);
47 if (!line) {
48 vty_out(vty, "Cannot find line %d%s", line_nr, VTY_NEWLINE);
49 return CMD_WARNING;
50 }
51 if (ts_nr >= line->num_ts) {
52 vty_out(vty, "Timeslot %d is too large%s", ts_nr, VTY_NEWLINE);
53 return CMD_WARNING;
54 }
Harald Welteb7e40232016-07-29 14:26:50 +020055 ts = &line->ts[ts_nr-1];
56 e1inp_line_bind_ops(line, &dummy_e1i_line_ops);
Harald Welte39cfbf42016-07-28 09:04:11 +020057
Harald Welteb7e40232016-07-29 14:26:50 +020058 vty_out(vty, "Line %u TS %u mode %u%s", line_nr, ts_nr, mode, VTY_NEWLINE);
Harald Welte39cfbf42016-07-28 09:04:11 +020059 switch (mode) {
60 case E1INP_TS_TYPE_NONE:
61 /* TOOD: have eqinp_ts_config_none ? */
62 ts->type = E1INP_TS_TYPE_NONE;
63 break;
Harald Welte13351132016-10-17 22:13:36 +020064 case E1INP_TS_TYPE_HDLC:
65 e1inp_ts_config_hdlc(ts, line, &e1ts_raw_recv);
Harald Welte39cfbf42016-07-28 09:04:11 +020066 break;
67 case E1INP_TS_TYPE_RAW:
68 e1inp_ts_config_raw(ts, line, &e1ts_raw_recv);
69 break;
Harald Welteb7e40232016-07-29 14:26:50 +020070 default:
71 vty_out(vty, "Unknown mode %u ?!?%s", mode, VTY_NEWLINE);
72 break;
Harald Welte39cfbf42016-07-28 09:04:11 +020073 }
74
75 /* notify driver of change */
76 e1inp_line_update(line);
77
78 return CMD_SUCCESS;
79}
80
81DEFUN(cfg_rec_line_mirror, cfg_rec_line_mirror_cmd,
82 "line <0-255> mirror <0-255>",
83 LINE_STR "Mirror this line to another line\n"
84 "E1/T1 Line Number\n")
85{
86 uint8_t line_nr = atoi(argv[0]);
87 uint8_t peer_nr = atoi(argv[1]);
88 struct e1_recorder_line *line = &g_recorder.line[line_nr];
89 struct e1_recorder_line *peer = &g_recorder.line[peer_nr];
90 /* look up morror peer and enable mirror flag on peer */
91 if (peer->mirror.enabled &&
92 peer->mirror.line_nr != line_nr) {
93 vty_out(vty, "Peer line %u already part of another mirror%s",
94 peer_nr, VTY_NEWLINE);
95 return CMD_WARNING;
96 }
97 peer->mirror.enabled = true;
98 peer->mirror.line_nr = line_nr;
99 /* enable mirror flag of current line */
100 if (line->mirror.enabled &&
101 line->mirror.line_nr != peer_nr) {
102 vty_out(vty, "Line %u already part of another mirror%s",
103 line_nr, VTY_NEWLINE);
104 return CMD_WARNING;
105 }
106 line->mirror.enabled = true;
107 line->mirror.line_nr = peer_nr;
108 return CMD_SUCCESS;
109}
110
111DEFUN(cfg_rec_no_line_mirror, cfg_rec_no_line_mirror_cmd,
112 "no line <0-255> mirror",
113 LINE_STR "Mirror this line to another line\n"
114 "E1/T1 Line Number\n")
115{
116 uint8_t line_nr = atoi(argv[0]);
117 struct e1_recorder_line *line = &g_recorder.line[line_nr];
118 struct e1_recorder_line *peer;
119
120 if (!line->mirror.enabled)
121 return CMD_WARNING;
122 /* look up morror peer (if any) and disable mirror flag on peer */
123 peer = &g_recorder.line[line->mirror.line_nr];
124 if (peer->mirror.enabled) {
125 peer->mirror.enabled = false;
126 peer->mirror.line_nr = 0;
127 }
128 /* dsiable mirror flag of current line */
129 if (line->mirror.enabled){
130 line->mirror.enabled = false;
131 line->mirror.line_nr = 0;
132 }
133 return CMD_SUCCESS;
134}
135
136
137DEFUN(cfg_rec_save_path, cfg_rec_save_path_cmd,
138 "storage-path PATH",
139 "Configure the directory for storing recordings\n"
140 "Directory to which recordings are stored\n")
141{
142 osmo_talloc_replace_string(NULL, &g_recorder.storage_path, argv[0]);
143 return CMD_SUCCESS;
144}
145
146DEFUN(cfg_rec_file_size, cfg_rec_file_size_cmd,
147 "file-size-mb <1-9999999>",
148 "Configure the maximum file size before starting new file\n"
149 "Megabytes\n")
150{
151 g_recorder.max_file_size_mb = atoi(argv[0]);
152 return CMD_SUCCESS;
153}
154
155static void config_write_recorder_line(struct vty *vty, unsigned int lnr)
156{
157 struct e1inp_line *line = e1inp_line_find(lnr);
158 struct e1_recorder_line *rline = &g_recorder.line[lnr];
159 unsigned int i;
160
161 if (rline->mirror.enabled) {
162 vty_out(vty, " line %u mirror %u%s",
163 lnr, rline->mirror.line_nr, VTY_NEWLINE);
164 }
165
166 if (!line)
167 return;
168
169 for (i = 0; i < line->num_ts; i++) {
170 struct e1inp_ts *ts = &line->ts[i];
Harald Welteb7e40232016-07-29 14:26:50 +0200171 const char *mode_str;
172
Harald Weltede9e6462019-12-04 11:58:37 +0100173 if (ts->type == E1INP_TS_TYPE_NONE)
174 continue;
175
Harald Welteb7e40232016-07-29 14:26:50 +0200176 mode_str = get_value_string(e1inp_ts_type_names, ts->type);
177
178 vty_out(vty, " line %u ts %u mode %s%s",
Harald Welte50595fb2019-12-04 11:52:04 +0100179 lnr, ts->num, osmo_str_tolower(mode_str), VTY_NEWLINE);
Harald Welte39cfbf42016-07-28 09:04:11 +0200180 }
181}
182
183static int config_write_recorder(struct vty *vty)
184{
185 unsigned int i;
186
187 vty_out(vty, "recorder%s", VTY_NEWLINE);
188 vty_out(vty, " file-size-mb %u%s", g_recorder.max_file_size_mb,
189 VTY_NEWLINE);
190 vty_out(vty, " storage-path %s%s", g_recorder.storage_path,
191 VTY_NEWLINE);
192 for (i = 0; i < 255; i++) {
193 config_write_recorder_line(vty, i);
194 }
195
196 return 0;
197}
198
199static struct cmd_node cfg_recorder_node = {
200 RECORDER_NODE,
201 "%s(config-recorder)# ",
202 1,
203};
204
205void recorder_vty_init(void)
206{
207 install_element(CONFIG_NODE, &cfg_recorder_cmd);
208
209 install_node(&cfg_recorder_node, config_write_recorder);
210 install_element(RECORDER_NODE, &cfg_rec_line_ts_mode_cmd);
211 install_element(RECORDER_NODE, &cfg_rec_line_mirror_cmd);
212 install_element(RECORDER_NODE, &cfg_rec_no_line_mirror_cmd);
213 install_element(RECORDER_NODE, &cfg_rec_save_path_cmd);
214 install_element(RECORDER_NODE, &cfg_rec_file_size_cmd);
215}