aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2017-11-29 14:01:35 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2017-11-29 14:05:09 +0100
commit2e9ea50f7824e2028e44a27b72d5ae268cfc66f0 (patch)
tree041818ead287024197956b12f8220ac52e1ed3f0
parent291efcb590c136fc5ce0e0f54d6ecd2630e2f3e2 (diff)
Add vty cmd 'cdr trap' to send CDR through CTRL iface
Default behavior is to have them disabled, and can be explicitly disabled too by using 'no cdr trap' cmd. Tested with osmo_ctrl.py that messages are send successfully: TRAP 0 cdr-v1 20171129125950222,901700000015254,357737055592090,555,0,5,,pdp-periodic,2731,127.0.0.2,127.0.0.1,internet,176.16.222.3,20793,10045,1 Related: OS#2360 Change-Id: I1d144d87effd934d991257a65e19cf046a938907
-rw-r--r--include/osmocom/sgsn/sgsn.h1
-rw-r--r--src/gprs/sgsn_cdr.c64
-rw-r--r--src/gprs/sgsn_main.c6
-rw-r--r--src/gprs/sgsn_vty.c26
4 files changed, 70 insertions, 27 deletions
diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h
index 464a64fe0..7e0b5d477 100644
--- a/include/osmocom/sgsn/sgsn.h
+++ b/include/osmocom/sgsn/sgsn.h
@@ -52,6 +52,7 @@ enum sgsn_rate_ctr_keys {
struct sgsn_cdr {
char *filename;
+ bool trap;
int interval;
};
diff --git a/src/gprs/sgsn_cdr.c b/src/gprs/sgsn_cdr.c
index bc051ac81..55aa66492 100644
--- a/src/gprs/sgsn_cdr.c
+++ b/src/gprs/sgsn_cdr.c
@@ -18,6 +18,8 @@
*
*/
+#include <osmocom/ctrl/control_if.h>
+
#include <osmocom/sgsn/sgsn.h>
#include <osmocom/sgsn/signal.h>
#include <osmocom/sgsn/gprs_utils.h>
@@ -38,6 +40,7 @@
/* TODO...avoid going through a global */
extern struct sgsn_instance *sgsn;
+extern struct ctrl_handle *g_ctrlh;
/**
* The CDR module will generate an entry like:
@@ -59,6 +62,11 @@ extern struct sgsn_instance *sgsn;
* CAUSE_FOR_TERM, # CAUSE_FOR_TERM
*/
+static void send_cdr_trap(char *value)
+{
+ if (ctrl_cmd_send_trap(g_ctrlh, "cdr-v1", value) < 0)
+ LOGP(DGPRS, LOGL_ERROR, "Failed to create and send TRAP cdr-v1\n");
+}
static void maybe_print_header(FILE *cdr_file)
{
@@ -97,21 +105,27 @@ static void cdr_log_mm(struct sgsn_instance *inst, const char *ev,
FILE *cdr_file;
char buf[1024];
- if (!inst->cfg.cdr.filename)
+ if (!inst->cfg.cdr.filename && !inst->cfg.cdr.trap)
return;
- cdr_file = fopen(inst->cfg.cdr.filename, "a");
- if (!cdr_file) {
- LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
- inst->cfg.cdr.filename);
- return;
- }
-
- maybe_print_header(cdr_file);
cdr_snprintf_mm(buf, sizeof(buf), ev, mmctx);
- fprintf(cdr_file, "%s\n", buf);
- fclose(cdr_file);
+ if (inst->cfg.cdr.trap)
+ send_cdr_trap(buf);
+
+ if (inst->cfg.cdr.filename) {
+ cdr_file = fopen(inst->cfg.cdr.filename, "a");
+ if (!cdr_file) {
+ LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
+ inst->cfg.cdr.filename);
+ return;
+ }
+
+ maybe_print_header(cdr_file);
+ fprintf(cdr_file, "%s\n", buf);
+
+ fclose(cdr_file);
+ }
}
static void extract_eua(struct ul66_t *eua, char *eua_addr)
@@ -200,20 +214,26 @@ static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev,
FILE *cdr_file;
char buf[1024];
- if (!inst->cfg.cdr.filename)
- return;
-
- cdr_file = fopen(inst->cfg.cdr.filename, "a");
- if (!cdr_file) {
- LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
- inst->cfg.cdr.filename);
+ if (!inst->cfg.cdr.filename && !inst->cfg.cdr.trap)
return;
- }
- maybe_print_header(cdr_file);
cdr_snprintf_pdp(buf, sizeof(buf), ev, pdp);
- fprintf(cdr_file, "%s\n", buf);
- fclose(cdr_file);
+
+ if (inst->cfg.cdr.trap)
+ send_cdr_trap(buf);
+
+ if (inst->cfg.cdr.filename) {
+ cdr_file = fopen(inst->cfg.cdr.filename, "a");
+ if (!cdr_file) {
+ LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
+ inst->cfg.cdr.filename);
+ return;
+ }
+
+ maybe_print_header(cdr_file);
+ fprintf(cdr_file, "%s\n", buf);
+ fclose(cdr_file);
+ }
}
static void cdr_pdp_timeout(void *_data)
diff --git a/src/gprs/sgsn_main.c b/src/gprs/sgsn_main.c
index fe4192bbd..b2a028c43 100644
--- a/src/gprs/sgsn_main.c
+++ b/src/gprs/sgsn_main.c
@@ -76,6 +76,7 @@
#include <getopt.h>
void *tall_bsc_ctx;
+struct ctrl_handle *g_ctrlh;
struct gprs_ns_inst *sgsn_nsi;
static int daemonize = 0;
@@ -367,7 +368,6 @@ static bool file_exists(const char *path)
int main(int argc, char **argv)
{
- struct ctrl_handle *ctrl;
int rc;
#if BUILD_IU
struct osmo_sccp_instance *sccp;
@@ -454,9 +454,9 @@ int main(int argc, char **argv)
/* start control interface after reading config for
* ctrl_vty_get_bind_addr() */
- ctrl = sgsn_controlif_setup(NULL, ctrl_vty_get_bind_addr(),
+ g_ctrlh = sgsn_controlif_setup(NULL, ctrl_vty_get_bind_addr(),
OSMO_CTRL_PORT_SGSN);
- if (!ctrl) {
+ if (!g_ctrlh) {
LOGP(DGPRS, LOGL_ERROR, "Failed to create CTRL interface.\n");
exit(1);
}
diff --git a/src/gprs/sgsn_vty.c b/src/gprs/sgsn_vty.c
index a01de2d7a..c8dfc437e 100644
--- a/src/gprs/sgsn_vty.c
+++ b/src/gprs/sgsn_vty.c
@@ -233,6 +233,10 @@ static int config_write_sgsn(struct vty *vty)
vty_out(vty, " cdr filename %s%s", g_cfg->cdr.filename, VTY_NEWLINE);
else
vty_out(vty, " no cdr filename%s", VTY_NEWLINE);
+ if (g_cfg->cdr.trap)
+ vty_out(vty, " cdr trap%s", VTY_NEWLINE);
+ else
+ vty_out(vty, " no cdr trap%s", VTY_NEWLINE);
vty_out(vty, " cdr interval %d%s", g_cfg->cdr.interval, VTY_NEWLINE);
vty_out(vty, " timer t3312 %d%s", g_cfg->timers.T3312, VTY_NEWLINE);
@@ -1100,7 +1104,7 @@ DEFUN(cfg_no_apn_name, cfg_no_apn_name_cmd,
DEFUN(cfg_cdr_filename, cfg_cdr_filename_cmd,
"cdr filename NAME",
- "CDR\nSet filename\nname\n")
+ "CDR\nEnable saving CDR to filename\nname\n")
{
talloc_free(g_cfg->cdr.filename);
g_cfg->cdr.filename = talloc_strdup(tall_vty_ctx, argv[0]);
@@ -1109,13 +1113,29 @@ DEFUN(cfg_cdr_filename, cfg_cdr_filename_cmd,
DEFUN(cfg_no_cdr_filename, cfg_no_cdr_filename_cmd,
"no cdr filename",
- NO_STR "CDR\nDisable CDR generation\n")
+ NO_STR "CDR\nDisable saving CDR to file\n")
{
talloc_free(g_cfg->cdr.filename);
g_cfg->cdr.filename = NULL;
return CMD_SUCCESS;
}
+DEFUN(cfg_cdr_trap, cfg_cdr_trap_cmd,
+ "cdr trap",
+ "CDR\nEnable sending CDR via TRAP CTRL messages\n")
+{
+ g_cfg->cdr.trap = true;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_cdr_trap, cfg_no_cdr_trap_cmd,
+ "no cdr trap",
+ NO_STR "CDR\nDisable sending CDR via TRAP CTRL messages\n")
+{
+ g_cfg->cdr.trap = false;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_cdr_interval, cfg_cdr_interval_cmd,
"cdr interval <1-2147483647>",
"CDR\nPDP periodic log interval\nSeconds\n")
@@ -1250,6 +1270,8 @@ int sgsn_vty_init(struct sgsn_config *cfg)
install_element(SGSN_NODE, &cfg_no_apn_name_cmd);
install_element(SGSN_NODE, &cfg_cdr_filename_cmd);
install_element(SGSN_NODE, &cfg_no_cdr_filename_cmd);
+ install_element(SGSN_NODE, &cfg_cdr_trap_cmd);
+ install_element(SGSN_NODE, &cfg_no_cdr_trap_cmd);
install_element(SGSN_NODE, &cfg_cdr_interval_cmd);
install_element(SGSN_NODE, &cfg_ggsn_dynamic_lookup_cmd);
install_element(SGSN_NODE, &cfg_grx_ggsn_cmd);