blob: 9110ccbdd4a39334b809205f30437539abd0e1fb [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 Weltedf7a3062016-10-19 10:47:17 +02003
Harald Welte39cfbf42016-07-28 09:04:11 +02004#include <osmocom/core/signal.h>
5#include <osmocom/core/logging.h>
6#include <osmocom/core/application.h>
7#include <osmocom/vty/vty.h>
8#include <osmocom/vty/telnet_interface.h>
Harald Welteb7e40232016-07-29 14:26:50 +02009#include <osmocom/vty/logging.h>
Harald Welte39cfbf42016-07-28 09:04:11 +020010
11#include <osmocom/abis/abis.h>
12#include <osmocom/abis/e1_input.h>
13
14#include "storage.h"
15#include "recorder.h"
16
17static enum osmo_e1cap_capture_mode ts2cap_mode(struct e1inp_ts *ts)
18{
19 switch (ts->type) {
20 case E1INP_TS_TYPE_RAW:
21 return OSMO_E1CAP_MODE_RAW;
Harald Welte13351132016-10-17 22:13:36 +020022 case E1INP_TS_TYPE_HDLC:
Harald Welte39cfbf42016-07-28 09:04:11 +020023 return OSMO_E1CAP_MODE_HDLC;
24 case E1INP_TS_TYPE_TRAU:
25 return OSMO_E1CAP_MODE_TRAU;
26 default:
27 OSMO_ASSERT(0);
28 }
29}
30
31/* receive a raw message frome the E1 timeslot */
32void e1ts_raw_recv(struct e1inp_ts *ts, struct msgb *msg)
33{
Harald Welte0e91aa12016-07-28 21:03:40 +020034 struct e1_recorder_line *rline = &g_recorder.line[ts->line->num];
Harald Welte39cfbf42016-07-28 09:04:11 +020035 enum osmo_e1cap_capture_mode cap_mode = ts2cap_mode(ts);
Harald Welte2ac78492016-10-19 10:47:41 +020036 int rc;
Harald Welte39cfbf42016-07-28 09:04:11 +020037
38 /* FIXME: special processing of TFP and PGSL */
39
Harald Welte2ac78492016-10-19 10:47:41 +020040 rc = e1frame_store(ts, msg, cap_mode);
41 if (rc < 0) {
42 LOGP(DMAIN, LOGL_FATAL, "Error writing E1/T1 frame to disk\n");
43 exit(1);
44 }
Harald Welte39cfbf42016-07-28 09:04:11 +020045
Harald Welte0e91aa12016-07-28 21:03:40 +020046 if (rline->mirror.enabled) {
Harald Welteb7e40232016-07-29 14:26:50 +020047 struct e1inp_line *other_line =
48 e1inp_line_find(rline->mirror.line_nr);
49 struct e1inp_ts *other_ts;
50 other_ts = &other_line->ts[ts->num-1];
Harald Welte4a92d0b2016-10-18 21:36:01 +020051 if (!other_ts) {
52 msgb_free(msg);
Harald Welteb7e40232016-07-29 14:26:50 +020053 return;
Harald Welte4a92d0b2016-10-18 21:36:01 +020054 }
Harald Welte39cfbf42016-07-28 09:04:11 +020055 /* forward data to destination line */
Harald Welteb7e40232016-07-29 14:26:50 +020056 OSMO_ASSERT(other_ts->type == ts->type);
57 msgb_enqueue(&other_ts->raw.tx_queue, msg);
Harald Welte4a92d0b2016-10-18 21:36:01 +020058 } else
59 msgb_free(msg);
Harald Welte39cfbf42016-07-28 09:04:11 +020060}
61
62static int inp_sig_cb(unsigned int subsys, unsigned int signal,
63 void *handler_data, void *signal_data)
64{
65 OSMO_ASSERT(subsys == SS_L_INPUT);
66
67 /* FIXME */
68
69 return 0;
70}
71
Harald Welte39cfbf42016-07-28 09:04:11 +020072static const struct log_info_cat recorder_categories[] = {
73 [DMAIN] = {
74 .name = "MAIN",
Harald Welteb7e40232016-07-29 14:26:50 +020075 .description = "Osmocom E1 Recorder",
Harald Welte39cfbf42016-07-28 09:04:11 +020076 .enabled = 1, .loglevel = LOGL_DEBUG,
77 },
78};
79static struct log_info info = {
80 .cat = recorder_categories,
81 .num_cat = ARRAY_SIZE(recorder_categories),
82};
83
84struct vty_app_info vty_info = {
85 .name = "osmo-e1-recorder",
86 .version = "0",
87 .copyright = "(C) 2016 by Harald Welte <laforge@gnumonks.org>\n",
88};
89
90static void *rec_tall_ctx;
91struct e1_recorder g_recorder;
Harald Welte4dc14a72016-10-19 10:53:47 +020092static char *g_config_file = "osmo-e1-recorder.cfg";
Harald Welte39cfbf42016-07-28 09:04:11 +020093
Harald Weltedf7a3062016-10-19 10:47:17 +020094static void signal_handler(int signo)
95{
96 switch (signo) {
97 case SIGHUP:
98 storage_close();
99 break;
100 case SIGUSR1:
101 talloc_report(rec_tall_ctx, stderr);
102 break;
103 }
104}
105
Harald Welte4dc14a72016-10-19 10:53:47 +0200106static void handle_options(int argc, char **argv)
107{
108 while (1) {
109 int option_index = 0, c;
110 static const struct option long_options[] = {
111 { "config-file", 1, 0, 'c' },
112 { 0, 0, 0, 0 }
113 };
114
115 c = getopt_long(argc, argv, "c:",
116 long_options, &option_index);
117 if (c == -1)
118 break;
119
120 switch (c) {
121 case 'c':
122 g_config_file = optarg;
123 break;
124 }
125 }
126}
127
Harald Welte39cfbf42016-07-28 09:04:11 +0200128int main(int argc, char **argv)
129{
130 int rc;
131
132 rec_tall_ctx = talloc_named_const(NULL, 0, "recorder");
133
134 osmo_init_logging(&info);
135 vty_init(&vty_info);
Harald Welteb7e40232016-07-29 14:26:50 +0200136 logging_vty_add_cmds(&info);
Harald Welte39cfbf42016-07-28 09:04:11 +0200137 osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
138 libosmo_abis_init(rec_tall_ctx);
139 e1inp_vty_init();
140 recorder_vty_init();
141
Harald Weltedf7a3062016-10-19 10:47:17 +0200142 signal(SIGHUP, &signal_handler);
143 signal(SIGUSR1, &signal_handler);
144
Harald Welte4dc14a72016-10-19 10:53:47 +0200145 handle_options(argc, argv);
146
147 rc = vty_read_config_file(g_config_file, NULL);
Harald Welte39cfbf42016-07-28 09:04:11 +0200148 if (rc < 0)
149 exit(1);
150
151 /* start telne tafte reading config for vty_get_bind_adr() */
152 telnet_init_dynif(rec_tall_ctx, NULL, vty_get_bind_addr(), 4444);
153
154 while (1) {
155 osmo_select_main(0);
156 };
157}