From 32266a9ad3384e0792f4e4fd662a00ad2cc2be79 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Mon, 30 Jan 2023 16:38:54 +0100 Subject: [PATCH] layer23: Support configuring GSMTAP through VTY in l23 apps. This allow all l23 apps supporting L23_OPT_VTY and L23_OPT_TAP to dynamically configure gsmtap through a "gsmtap" VTY node: gsmtap gsmtap-remote-host 127.0.0.2 gsmtap-sapi bcch gsmtap-sapi ccch gsmtap-sapi rach gsmtap-sapi agch gsmtap-sapi pch gsmtap-sapi sdcch gsmtap-sapi tch/f gsmtap-sapi tch/h gsmtap-sapi pacch gsmtap-sapi pdtch gsmtap-sapi ptcch gsmtap-sapi cbch gsmtap-category gprs dl-unknown gsmtap-category gprs dl-dummy gsmtap-category gprs dl-ctrl gsmtap-category gprs dl-data-gprs gsmtap-category gprs dl-data-egprs gsmtap-category gprs ul-unknown gsmtap-category gprs ul-dummy gsmtap-category gprs ul-ctrl gsmtap-category gprs ul-data-gprs gsmtap-category gprs ul-data-egprs VTY cmd "gsmtap-sapi" enables/disables tapping on general channel types, while "gsmtap-category" allows fine-grained selection of messages being tapped within the enabled sapis which would tap those messages. Change-Id: I2582a1633d37d350a7f4c2bb5e03793bdf46e839 --- .../include/osmocom/bb/common/l23_app.h | 24 ++ .../layer23/include/osmocom/bb/common/vty.h | 1 + src/host/layer23/src/common/l1ctl.c | 7 +- src/host/layer23/src/common/main.c | 31 ++- src/host/layer23/src/common/sim.c | 5 +- src/host/layer23/src/common/vty.c | 258 +++++++++++++++++- src/host/layer23/src/mobile/main.c | 8 +- 7 files changed, 314 insertions(+), 20 deletions(-) diff --git a/src/host/layer23/include/osmocom/bb/common/l23_app.h b/src/host/layer23/include/osmocom/bb/common/l23_app.h index d442e7e2b..c9b66d439 100644 --- a/src/host/layer23/include/osmocom/bb/common/l23_app.h +++ b/src/host/layer23/include/osmocom/bb/common/l23_app.h @@ -2,6 +2,7 @@ #define _L23_APP_H #include +#include struct option; struct vty_app_info; @@ -15,6 +16,29 @@ enum { L23_OPT_DBG = 1 << 4, }; +/* see bts->gsmtap_categ_mask */ +enum l23_gsmtap_category { + L23_GSMTAP_C_DL_UNKNOWN = 0, /* unknown or undecodable downlink blocks */ + L23_GSMTAP_C_DL_DUMMY = 1, /* downlink dummy blocks */ + L23_GSMTAP_C_DL_CTRL = 2, /* downlink control blocks */ + L23_GSMTAP_C_DL_DATA_GPRS = 3, /* downlink GPRS data blocks */ + L23_GSMTAP_C_DL_DATA_EGPRS = 4, /* downlink EGPRS data blocks */ + + L23_GSMTAP_C_UL_UNKNOWN = 5, /* unknown or undecodable uplink blocks */ + L23_GSMTAP_C_UL_DUMMY = 6, /* uplink dummy blocks */ + L23_GSMTAP_C_UL_CTRL = 7, /* uplink control blocks */ + L23_GSMTAP_C_UL_DATA_GPRS = 8, /* uplink GPRS data blocks */ + L23_GSMTAP_C_UL_DATA_EGPRS = 9, /* uplink EGPRS data blocks */ +}; + +struct l23_global_config { + char *gsmtap_remote_host; + uint32_t gsmtap_sapi_mask; /* see l23_gsmtap_category */ + uint32_t gsmtap_categ_gprs_mask; + struct gsmtap_inst *gsmtap_inst; +}; +extern struct l23_global_config l23_cfg; + extern void *l23_ctx; /* initialization, called once when starting the app, before reading VTY config */ diff --git a/src/host/layer23/include/osmocom/bb/common/vty.h b/src/host/layer23/include/osmocom/bb/common/vty.h index 259725eb3..4ff96fe56 100644 --- a/src/host/layer23/include/osmocom/bb/common/vty.h +++ b/src/host/layer23/include/osmocom/bb/common/vty.h @@ -10,6 +10,7 @@ struct osmocom_ms; enum l23_vty_node { MS_NODE = _LAST_OSMOVTY_NODE + 1, + GSMTAP_NODE, _LAST_L23VTY_NODE, }; diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c index 5ba1a1fb4..95b1e9a90 100644 --- a/src/host/layer23/src/common/l1ctl.c +++ b/src/host/layer23/src/common/l1ctl.c @@ -39,14 +39,13 @@ #include #include +#include #include #include #include #include #include -extern struct gsmtap_inst *gsmtap_inst; - #define CB_FCCH -1 #define CB_SCH -2 #define CB_BCCH -3 @@ -317,7 +316,7 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg) * to clog up your logs */ if (!is_fill_frame(gsmtap_chan_type, ccch->data)) { /* send CCCH data via GSMTAP */ - gsmtap_send(gsmtap_inst, ntohs(dl->band_arfcn), chan_ts, + gsmtap_send(l23_cfg.gsmtap_inst, ntohs(dl->band_arfcn), chan_ts, gsmtap_chan_type, chan_ss, tm.fn, dl->rx_level-110, dl->snr, ccch->data, sizeof(ccch->data)); } @@ -394,7 +393,7 @@ int l1ctl_tx_data_req(struct osmocom_ms *ms, struct msgb *msg, /* send copy via GSMTAP */ if (rsl_dec_chan_nr(chan_nr, &chan_type, &chan_ss, &chan_ts) == 0) { uint8_t gsmtap_chan_type = chantype_rsl2gsmtap2(chan_type, link_id, false); - gsmtap_send(gsmtap_inst, ms->rrlayer.cd_now.arfcn | GSMTAP_ARFCN_F_UPLINK, + gsmtap_send(l23_cfg.gsmtap_inst, ms->rrlayer.cd_now.arfcn | GSMTAP_ARFCN_F_UPLINK, chan_ts, gsmtap_chan_type, chan_ss, 0, 127, 0, msg->l2h, msgb_l2len(msg)); } else { diff --git a/src/host/layer23/src/common/main.c b/src/host/layer23/src/common/main.c index 82bbc6005..92a4325d0 100644 --- a/src/host/layer23/src/common/main.c +++ b/src/host/layer23/src/common/main.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -53,6 +52,7 @@ #include "config.h" void *l23_ctx = NULL; +struct l23_global_config l23_cfg; static char *sap_socket_path = "/tmp/osmocom_sap"; struct llist_head ms_list; @@ -63,7 +63,6 @@ int (*l23_app_start)(void) = NULL; int (*l23_app_work)(void) = NULL; int (*l23_app_exit)(void) = NULL; int quit = 0; -struct gsmtap_inst *gsmtap_inst; const char *openbsc_copyright = "%s" @@ -288,13 +287,29 @@ int main(int argc, char **argv) exit(1); } - if (gsmtap_ip) { - gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1); - if (!gsmtap_inst) { - fprintf(stderr, "Failed during gsmtap_init()\n"); - exit(1); + if (app_supp_opt & L23_OPT_TAP) { + if (gsmtap_ip) { + if (l23_cfg.gsmtap_remote_host != NULL) { + LOGP(DLGLOBAL, LOGL_NOTICE, + "Command line argument '-i %s' overrides " + "'gsmtap-remote-host %s' from the config file\n", + gsmtap_ip, l23_cfg.gsmtap_remote_host); + talloc_free(l23_cfg.gsmtap_remote_host); + } + l23_cfg.gsmtap_remote_host = talloc_strdup(l23_ctx, gsmtap_ip); + } + + if (l23_cfg.gsmtap_remote_host) { + LOGP(DLGLOBAL, LOGL_NOTICE, + "Setting up GSMTAP Um forwarding to '%s:%u'\n", + l23_cfg.gsmtap_remote_host, GSMTAP_UDP_PORT); + l23_cfg.gsmtap_inst = gsmtap_source_init(l23_cfg.gsmtap_remote_host, GSMTAP_UDP_PORT, 1); + if (!l23_cfg.gsmtap_inst) { + fprintf(stderr, "Failed during gsmtap_init()\n"); + exit(1); + } + gsmtap_source_add_sink(l23_cfg.gsmtap_inst); } - gsmtap_source_add_sink(gsmtap_inst); } if (l23_app_start) { diff --git a/src/host/layer23/src/common/sim.c b/src/host/layer23/src/common/sim.c index bd50f6273..34abbc212 100644 --- a/src/host/layer23/src/common/sim.c +++ b/src/host/layer23/src/common/sim.c @@ -24,12 +24,11 @@ #include #include +#include #include #include #include -extern struct gsmtap_inst *gsmtap_inst; - static int sim_process_job(struct osmocom_ms *ms); /* @@ -874,7 +873,7 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg) if ((ms->sim.apdu_len + length) <= sizeof(ms->sim.apdu_data)) { memcpy(ms->sim.apdu_data + ms->sim.apdu_len, data, length); ms->sim.apdu_len += length; - gsmtap_send_ex(gsmtap_inst, GSMTAP_TYPE_SIM, + gsmtap_send_ex(l23_cfg.gsmtap_inst, GSMTAP_TYPE_SIM, 0, 0, 0, 0, 0, 0, 0, ms->sim.apdu_data, ms->sim.apdu_len); } } diff --git a/src/host/layer23/src/common/vty.c b/src/host/layer23/src/common/vty.c index 2e7dea88b..e3a48bc18 100644 --- a/src/host/layer23/src/common/vty.c +++ b/src/host/layer23/src/common/vty.c @@ -26,9 +26,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -38,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -52,6 +53,12 @@ static struct cmd_node ms_node = { 1 }; +static struct cmd_node gsmtap_node = { + GSMTAP_NODE, + "%s(gsmtap)# ", + 1 +}; + static void l23_vty_restart_required_warn(struct vty *vty, struct osmocom_ms *ms) { if (l23_vty_reading) @@ -120,6 +127,168 @@ void l23_ms_dump(struct osmocom_ms *ms, struct vty *vty) VTY_NEWLINE); } +/* "gsmtap" config */ +gDEFUN(l23_cfg_gsmtap, l23_cfg_gsmtap_cmd, "gsmtap", + "Configure GSMTAP\n") +{ + vty->node = GSMTAP_NODE; + return CMD_SUCCESS; +} + +static const struct value_string gsmtap_sapi_names[] = { + { GSMTAP_CHANNEL_BCCH, "BCCH" }, + { GSMTAP_CHANNEL_CCCH, "CCCH" }, + { GSMTAP_CHANNEL_RACH, "RACH" }, + { GSMTAP_CHANNEL_AGCH, "AGCH" }, + { GSMTAP_CHANNEL_PCH, "PCH" }, + { GSMTAP_CHANNEL_SDCCH, "SDCCH" }, + { GSMTAP_CHANNEL_TCH_F, "TCH/F" }, + { GSMTAP_CHANNEL_TCH_H, "TCH/H" }, + { GSMTAP_CHANNEL_PACCH, "PACCH" }, + { GSMTAP_CHANNEL_PDCH, "PDTCH" }, + { GSMTAP_CHANNEL_PTCCH, "PTCCH" }, + { GSMTAP_CHANNEL_CBCH51, "CBCH" }, + { GSMTAP_CHANNEL_ACCH, "SACCH" }, + { 0, NULL } +}; + +static const struct value_string gsmtap_categ_gprs_names[] = { + { L23_GSMTAP_C_DL_UNKNOWN, "dl-unknown" }, + { L23_GSMTAP_C_DL_DUMMY, "dl-dummy" }, + { L23_GSMTAP_C_DL_CTRL, "dl-ctrl" }, + { L23_GSMTAP_C_DL_DATA_GPRS, "dl-data-gprs" }, + { L23_GSMTAP_C_DL_DATA_EGPRS, "dl-data-egprs" }, + { L23_GSMTAP_C_UL_UNKNOWN, "ul-unknown" }, + { L23_GSMTAP_C_UL_DUMMY, "ul-dummy" }, + { L23_GSMTAP_C_UL_CTRL, "ul-ctrl" }, + { L23_GSMTAP_C_UL_DATA_GPRS, "ul-data-gprs" }, + { L23_GSMTAP_C_UL_DATA_EGPRS, "ul-data-egprs" }, + { 0, NULL } +}; + +static const struct value_string gsmtap_categ_gprs_help[] = { + { L23_GSMTAP_C_DL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" }, + { L23_GSMTAP_C_DL_DUMMY, "Downlink Dummy Blocks" }, + { L23_GSMTAP_C_DL_CTRL, "Downlink Control Blocks" }, + { L23_GSMTAP_C_DL_DATA_GPRS, "Downlink Data Blocks (GPRS)" }, + { L23_GSMTAP_C_DL_DATA_EGPRS, "Downlink Data Blocks (EGPRS)" }, + { L23_GSMTAP_C_UL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" }, + { L23_GSMTAP_C_UL_DUMMY, "Uplink Dummy Blocks" }, + { L23_GSMTAP_C_UL_CTRL, "Uplink Control Blocks" }, + { L23_GSMTAP_C_UL_DATA_GPRS, "Uplink Data Blocks (GPRS)" }, + { L23_GSMTAP_C_UL_DATA_EGPRS, "Uplink Data Blocks (EGPRS)" }, + { 0, NULL } +}; + +DEFUN(cfg_gsmtap_gsmtap_remote_host, + cfg_gsmtap_gsmtap_remote_host_cmd, + "gsmtap-remote-host [HOSTNAME]", + "Enable GSMTAP Um logging (see also 'gsmtap-category')\n" + "Remote IP address or hostname ('localhost' if omitted)\n") +{ + osmo_talloc_replace_string(l23_ctx, &l23_cfg.gsmtap_remote_host, + argc > 0 ? argv[0] : "localhost"); + + if (vty->type != VTY_FILE) + vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE); + + return CMD_SUCCESS; +} + +DEFUN(cfg_gsmtap_no_gsmtap_remote_host, + cfg_gsmtap_no_gsmtap_remote_host_cmd, + "no gsmtap-remote-host", + NO_STR "Disable GSMTAP Um logging\n") +{ + if (l23_cfg.gsmtap_remote_host) + TALLOC_FREE(l23_cfg.gsmtap_remote_host); + + if (vty->type != VTY_FILE) + vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE); + + return CMD_SUCCESS; +} + +DEFUN(cfg_gsmtap_gsmtap_sapi_all, cfg_gsmtap_gsmtap_sapi_all_cmd, + "gsmtap-sapi (enable-all|disable-all)", + "Enable/disable sending of UL/DL messages over GSMTAP\n" + "Enable all kinds of messages (all SAPI)\n" + "Disable all kinds of messages (all SAPI)\n") +{ + if (argv[0][0] == 'e') + l23_cfg.gsmtap_sapi_mask = UINT32_MAX; + else + l23_cfg.gsmtap_sapi_mask = 0x00; + + return CMD_SUCCESS; +} + +DEFUN(cfg_gsmtap_gsmtap_sapi, cfg_gsmtap_gsmtap_sapi_cmd, + "HIDDEN", "HIDDEN") +{ + int sapi; + + sapi = get_string_value(gsmtap_sapi_names, argv[0]); + OSMO_ASSERT(sapi >= 0); + l23_cfg.gsmtap_sapi_mask |= (1 << sapi); + + return CMD_SUCCESS; +} + +DEFUN(cfg_gsmtap_no_gsmtap_sapi, cfg_gsmtap_no_gsmtap_sapi_cmd, + "HIDDEN", "HIDDEN") +{ + int sapi; + + sapi = get_string_value(gsmtap_sapi_names, argv[0]); + OSMO_ASSERT(sapi >= 0); + + l23_cfg.gsmtap_sapi_mask &= ~(1 << sapi); + + return CMD_SUCCESS; +} + +DEFUN(cfg_gsmtap_gsmtap_categ_gprs_all, cfg_gsmtap_gsmtap_categ_gprs_all_cmd, + "gsmtap-category gprs (enable-all|disable-all)", + "Enable/disable sending of UL/DL messages over GSMTAP\n" + "Enable all kinds of messages (all categories)\n" + "Disable all kinds of messages (all categories)\n") +{ + + if (strcmp(argv[0], "enable-all") == 0) + l23_cfg.gsmtap_categ_gprs_mask = UINT32_MAX; + else + l23_cfg.gsmtap_categ_gprs_mask = 0x00; + + return CMD_SUCCESS; +} + +DEFUN(cfg_gsmtap_gsmtap_categ_gprs, cfg_gsmtap_gsmtap_categ_gprs_cmd, "HIDDEN", "HIDDEN") +{ + int categ; + + categ = get_string_value(gsmtap_categ_gprs_names, argv[0]); + if (categ < 0) + return CMD_WARNING; + + l23_cfg.gsmtap_categ_gprs_mask |= (1 << categ); + + return CMD_SUCCESS; +} + +DEFUN(cfg_gsmtap_no_gsmtap_categ_gprs, cfg_gsmtap_no_gsmtap_categ_gprs_cmd, "HIDDEN", "HIDDEN") +{ + int categ; + + categ = get_string_value(gsmtap_categ_gprs_names, argv[0]); + if (categ < 0) + return CMD_WARNING; + + l23_cfg.gsmtap_categ_gprs_mask &= ~(1 << categ); + + return CMD_SUCCESS; +} + gDEFUN(l23_show_ms, l23_show_ms_cmd, "show ms [MS_NAME]", SHOW_STR "Display available MS entities\n") @@ -228,6 +397,40 @@ DEFUN(cfg_ms_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force", return data.ms_stop.rc; } +static int l23_vty_config_write_gsmtap_node(struct vty *vty) +{ + const char *sapi_buf; + unsigned int i; + + vty_out(vty, "gsmtap%s", VTY_NEWLINE); + + if (l23_cfg.gsmtap_remote_host) + vty_out(vty, " gsmtap-remote-host %s%s", l23_cfg.gsmtap_remote_host, VTY_NEWLINE); + else + vty_out(vty, " no gsmtap-remote-host%s", VTY_NEWLINE); + + for (i = 0; i < sizeof(uint32_t) * 8; i++) { + if (l23_cfg.gsmtap_sapi_mask & ((uint32_t) 1 << i)) { + sapi_buf = get_value_string_or_null(gsmtap_sapi_names, i); + if (sapi_buf == NULL) + continue; + sapi_buf = osmo_str_tolower(sapi_buf); + vty_out(vty, " gsmtap-sapi %s%s", sapi_buf, VTY_NEWLINE); + } + } + + for (i = 0; i < 32; i++) { + if (l23_cfg.gsmtap_categ_gprs_mask & ((uint32_t)1 << i)) { + const char *category_buf; + if (!(category_buf = get_value_string_or_null(gsmtap_categ_gprs_names, i))) + continue; + vty_out(vty, " gsmtap-category gprs %s%s", category_buf, VTY_NEWLINE); + } + } + + return CMD_SUCCESS; +} + void l23_vty_config_write_ms_node(struct vty *vty, const struct osmocom_ms *ms, const char *prefix) { size_t prefix_len = strlen(prefix); @@ -260,9 +463,62 @@ void l23_vty_config_write_ms_node_contents_final(struct vty *vty, const struct o vty_out(vty, "!%s", VTY_NEWLINE); } +static void l23_vty_init_gsmtap(void) +{ + cfg_gsmtap_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names, + "gsmtap-sapi (", + "|", ")", VTY_DO_LOWER); + cfg_gsmtap_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names, + "Enable sending of UL/DL messages over GSMTAP\n", + "\n", "", 0); + + cfg_gsmtap_no_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names, + "no gsmtap-sapi (", + "|", ")", VTY_DO_LOWER); + cfg_gsmtap_no_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names, + NO_STR "Disable sending of UL/DL messages over GSMTAP\n", + "\n", "", 0); + + + cfg_gsmtap_gsmtap_categ_gprs_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_names, + "gsmtap-category gprs (", + "|", ")", VTY_DO_LOWER); + cfg_gsmtap_gsmtap_categ_gprs_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_help, + "GSMTAP Category\n" "GPRS\n", + "\n", "", 0); + cfg_gsmtap_no_gsmtap_categ_gprs_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_names, + "no gsmtap-category gprs (", + "|", ")", VTY_DO_LOWER); + cfg_gsmtap_no_gsmtap_categ_gprs_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_help, + NO_STR "GSMTAP Category\n" "GPRS\n", + "\n", "", 0); + + install_element(CONFIG_NODE, &l23_cfg_gsmtap_cmd); + + install_node(&gsmtap_node, l23_vty_config_write_gsmtap_node); + install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_remote_host_cmd); + install_element(GSMTAP_NODE, &cfg_gsmtap_no_gsmtap_remote_host_cmd); + install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_sapi_all_cmd); + install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_sapi_cmd); + install_element(GSMTAP_NODE, &cfg_gsmtap_no_gsmtap_sapi_cmd); + install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_categ_gprs_all_cmd); + install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_categ_gprs_cmd); + install_element(GSMTAP_NODE, &cfg_gsmtap_no_gsmtap_categ_gprs_cmd); +} + int l23_vty_init(int (*config_write_ms_node_cb)(struct vty *), osmo_signal_cbfn *l23_vty_signal_cb) { + struct l23_app_info *app; + unsigned int app_supp_opt = 0x00; int rc = 0; + + app = l23_app_info(); + if (app && app->cfg_supported != NULL) + app_supp_opt = app->cfg_supported(); + + if (app_supp_opt & L23_OPT_TAP) + l23_vty_init_gsmtap(); + install_node(&ms_node, config_write_ms_node_cb); install_element(MS_NODE, &cfg_ms_layer2_cmd); install_element(MS_NODE, &cfg_ms_shutdown_cmd); diff --git a/src/host/layer23/src/mobile/main.c b/src/host/layer23/src/mobile/main.c index 4627b25e4..881c283f5 100644 --- a/src/host/layer23/src/mobile/main.c +++ b/src/host/layer23/src/mobile/main.c @@ -51,10 +51,10 @@ #include "config.h" void *l23_ctx = NULL; +struct l23_global_config l23_cfg; struct llist_head ms_list; static char *gsmtap_ip = 0; static const char *custom_cfg_file = NULL; -struct gsmtap_inst *gsmtap_inst = NULL; static char *config_file = NULL; char *config_dir = NULL; int daemonize = 0; @@ -315,12 +315,12 @@ int main(int argc, char **argv) } if (gsmtap_ip) { - gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1); - if (!gsmtap_inst) { + l23_cfg.gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1); + if (!l23_cfg.gsmtap_inst) { fprintf(stderr, "Failed during gsmtap_init()\n"); exit(1); } - gsmtap_source_add_sink(gsmtap_inst); + gsmtap_source_add_sink(l23_cfg.gsmtap_inst); } if (l23_app_start) {