blob: 82558b21a742b96131f7035405b70e82b195c4c6 [file] [log] [blame]
Harald Weltedf7a3062016-10-19 10:47:17 +02001#include <signal.h>
Harald Welte4dc14a72016-10-19 10:53:47 +02002#include <getopt.h>
Harald Welte2c5c0792019-12-04 11:35:14 +01003#include <errno.h>
Harald Weltedf7a3062016-10-19 10:47:17 +02004
Harald Welte39cfbf42016-07-28 09:04:11 +02005#include <osmocom/core/signal.h>
6#include <osmocom/core/logging.h>
7#include <osmocom/core/application.h>
8#include <osmocom/vty/vty.h>
9#include <osmocom/vty/telnet_interface.h>
Harald Welteb7e40232016-07-29 14:26:50 +020010#include <osmocom/vty/logging.h>
Harald Welte39cfbf42016-07-28 09:04:11 +020011
12#include <osmocom/abis/abis.h>
13#include <osmocom/abis/e1_input.h>
14
15#include "storage.h"
16#include "recorder.h"
17
Harald Welte06e31982019-12-03 22:06:17 +010018#include "config.h"
19
Harald Welte39cfbf42016-07-28 09:04:11 +020020static enum osmo_e1cap_capture_mode ts2cap_mode(struct e1inp_ts *ts)
21{
22 switch (ts->type) {
23 case E1INP_TS_TYPE_RAW:
24 return OSMO_E1CAP_MODE_RAW;
Harald Welte13351132016-10-17 22:13:36 +020025 case E1INP_TS_TYPE_HDLC:
Harald Welte39cfbf42016-07-28 09:04:11 +020026 return OSMO_E1CAP_MODE_HDLC;
27 case E1INP_TS_TYPE_TRAU:
28 return OSMO_E1CAP_MODE_TRAU;
29 default:
30 OSMO_ASSERT(0);
31 }
32}
33
34/* receive a raw message frome the E1 timeslot */
35void e1ts_raw_recv(struct e1inp_ts *ts, struct msgb *msg)
36{
Harald Welte0e91aa12016-07-28 21:03:40 +020037 struct e1_recorder_line *rline = &g_recorder.line[ts->line->num];
Harald Welte39cfbf42016-07-28 09:04:11 +020038 enum osmo_e1cap_capture_mode cap_mode = ts2cap_mode(ts);
Harald Welte2ac78492016-10-19 10:47:41 +020039 int rc;
Harald Welte39cfbf42016-07-28 09:04:11 +020040
41 /* FIXME: special processing of TFP and PGSL */
42
Harald Welte2ac78492016-10-19 10:47:41 +020043 rc = e1frame_store(ts, msg, cap_mode);
44 if (rc < 0) {
45 LOGP(DMAIN, LOGL_FATAL, "Error writing E1/T1 frame to disk\n");
46 exit(1);
47 }
Harald Welte39cfbf42016-07-28 09:04:11 +020048
Harald Welte0e91aa12016-07-28 21:03:40 +020049 if (rline->mirror.enabled) {
Harald Welteb7e40232016-07-29 14:26:50 +020050 struct e1inp_line *other_line =
51 e1inp_line_find(rline->mirror.line_nr);
52 struct e1inp_ts *other_ts;
53 other_ts = &other_line->ts[ts->num-1];
Harald Welte4a92d0b2016-10-18 21:36:01 +020054 if (!other_ts) {
55 msgb_free(msg);
Harald Welteb7e40232016-07-29 14:26:50 +020056 return;
Harald Welte4a92d0b2016-10-18 21:36:01 +020057 }
Harald Welte39cfbf42016-07-28 09:04:11 +020058 /* forward data to destination line */
Harald Welteb7e40232016-07-29 14:26:50 +020059 OSMO_ASSERT(other_ts->type == ts->type);
60 msgb_enqueue(&other_ts->raw.tx_queue, msg);
Harald Welte4a92d0b2016-10-18 21:36:01 +020061 } else
62 msgb_free(msg);
Harald Welte39cfbf42016-07-28 09:04:11 +020063}
64
65static int inp_sig_cb(unsigned int subsys, unsigned int signal,
66 void *handler_data, void *signal_data)
67{
68 OSMO_ASSERT(subsys == SS_L_INPUT);
69
70 /* FIXME */
71
72 return 0;
73}
74
Harald Welte39cfbf42016-07-28 09:04:11 +020075static const struct log_info_cat recorder_categories[] = {
76 [DMAIN] = {
77 .name = "MAIN",
Harald Welteb7e40232016-07-29 14:26:50 +020078 .description = "Osmocom E1 Recorder",
Harald Welte39cfbf42016-07-28 09:04:11 +020079 .enabled = 1, .loglevel = LOGL_DEBUG,
80 },
81};
82static struct log_info info = {
83 .cat = recorder_categories,
84 .num_cat = ARRAY_SIZE(recorder_categories),
85};
86
87struct vty_app_info vty_info = {
88 .name = "osmo-e1-recorder",
Harald Welte06e31982019-12-03 22:06:17 +010089 .version = PACKAGE_VERSION,
90 .copyright = "(C) 2016-2019 by Harald Welte <laforge@gnumonks.org>\n",
Harald Welte39cfbf42016-07-28 09:04:11 +020091};
92
93static void *rec_tall_ctx;
94struct e1_recorder g_recorder;
Harald Welte4dc14a72016-10-19 10:53:47 +020095static char *g_config_file = "osmo-e1-recorder.cfg";
Harald Welte39cfbf42016-07-28 09:04:11 +020096
Harald Weltedf7a3062016-10-19 10:47:17 +020097static void signal_handler(int signo)
98{
99 switch (signo) {
100 case SIGHUP:
101 storage_close();
102 break;
103 case SIGUSR1:
104 talloc_report(rec_tall_ctx, stderr);
105 break;
106 }
107}
108
Harald Welte06e31982019-12-03 22:06:17 +0100109static void print_help(void)
110{
111 printf( " -h --help This help\n"
112 " -V --version Print version of the program\n"
113 " -c --config FILE Specify configuration file\n"
114 );
115}
116
Harald Welte4dc14a72016-10-19 10:53:47 +0200117static void handle_options(int argc, char **argv)
118{
119 while (1) {
120 int option_index = 0, c;
121 static const struct option long_options[] = {
122 { "config-file", 1, 0, 'c' },
Harald Welte06e31982019-12-03 22:06:17 +0100123 { "help", 0, 0, 'h' },
124 { "version", 0, 0, 'V' },
Harald Welte4dc14a72016-10-19 10:53:47 +0200125 { 0, 0, 0, 0 }
126 };
127
Harald Welte06e31982019-12-03 22:06:17 +0100128 c = getopt_long(argc, argv, "c:hV",
Harald Welte4dc14a72016-10-19 10:53:47 +0200129 long_options, &option_index);
130 if (c == -1)
131 break;
132
133 switch (c) {
134 case 'c':
135 g_config_file = optarg;
136 break;
Harald Welte06e31982019-12-03 22:06:17 +0100137 case 'h':
138 print_help();
139 exit(0);
140 break;
141 case 'V':
142 print_version(1);
143 exit(0);
144 break;
Harald Welte4dc14a72016-10-19 10:53:47 +0200145 }
146 }
Harald Weltecbf23b62019-12-03 22:14:20 +0100147
148 if (argc > optind) {
149 fprintf(stderr, "Unsupported positional arguments on command line\n");
150 exit(2);
151 }
Harald Welte4dc14a72016-10-19 10:53:47 +0200152}
153
Harald Welte39cfbf42016-07-28 09:04:11 +0200154int main(int argc, char **argv)
155{
156 int rc;
157
158 rec_tall_ctx = talloc_named_const(NULL, 0, "recorder");
159
Harald Welte45e12d32019-12-04 14:14:54 +0100160 osmo_init_logging2(rec_tall_ctx, &info);
Harald Welte39cfbf42016-07-28 09:04:11 +0200161 vty_init(&vty_info);
Harald Welteb7e40232016-07-29 14:26:50 +0200162 logging_vty_add_cmds(&info);
Harald Welte39cfbf42016-07-28 09:04:11 +0200163 osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
164 libosmo_abis_init(rec_tall_ctx);
165 e1inp_vty_init();
166 recorder_vty_init();
167
Harald Weltedf7a3062016-10-19 10:47:17 +0200168 signal(SIGHUP, &signal_handler);
169 signal(SIGUSR1, &signal_handler);
170
Harald Welte4dc14a72016-10-19 10:53:47 +0200171 handle_options(argc, argv);
172
173 rc = vty_read_config_file(g_config_file, NULL);
Harald Welte2c5c0792019-12-04 11:35:14 +0100174 if (rc < 0) {
175 fprintf(stderr, "Cannot parse configuration file '%s': %s\n", g_config_file,
176 strerror(errno));
Harald Welte39cfbf42016-07-28 09:04:11 +0200177 exit(1);
Harald Welte2c5c0792019-12-04 11:35:14 +0100178 }
Harald Welte39cfbf42016-07-28 09:04:11 +0200179
180 /* start telne tafte reading config for vty_get_bind_adr() */
181 telnet_init_dynif(rec_tall_ctx, NULL, vty_get_bind_addr(), 4444);
182
183 while (1) {
184 osmo_select_main(0);
185 };
186}