neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32620 )
Change subject: move main() to separate file ...................................................................... move main() to separate file Conform to recent osmocom practice by having an osmo_hnbgw_main.c file for main() and its immediate infrastructure. Prepares for adding a non-installed libhnbgw.la -- which must not contain a main() function -- so that linking regression tests is easy. Separating to a new file seems appropriate because hnbgw.c has gathered a bunch of stuff that is not strictly main() related / might be useful to access in a C test. Change-Id: I5f26a6b68f0d380617d73371f40f3b9055cac362 --- M include/osmocom/hnbgw/hnbgw.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c A src/osmo-hnbgw/osmo_hnbgw_main.c 4 files changed, 417 insertions(+), 379 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/20/32620/1 diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 954a356..e3ec38b 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -23,6 +23,9 @@ DCN, }; +extern const struct log_info hnbgw_log_info; +extern struct vty_app_info hnbgw_vty_info; + #define LOGHNB(HNB_CTX, ss, lvl, fmt, args ...) \ LOGP(ss, lvl, "(%s) " fmt, hnb_context_name(HNB_CTX), ## args) @@ -171,7 +174,13 @@ extern struct hnbgw *g_hnbgw; extern void *talloc_asn1_ctx; -struct hnb_context *hnb_context_by_id(uint32_t cid); +void g_hnbgw_alloc(void *ctx); + +int hnbgw_rua_accept_cb(struct osmo_stream_srv_link *srv, int fd); +int hnb_ctrl_cmds_install(void); +int hnb_ctrl_node_lookup(void *data, vector vline, int *node_type, void **node_data, int *i); +int hnbgw_mgw_setup(void); + struct hnb_context *hnb_context_by_identity_info(const char *identity_info); const char *hnb_context_name(struct hnb_context *ctx); @@ -182,7 +191,6 @@ uint32_t tmsi); void ue_context_free(struct ue_context *ue); -struct hnb_context *hnb_context_alloc(struct osmo_stream_srv_link *link, int new_fd); void hnb_context_release(struct hnb_context *ctx); void hnb_context_release_ue_state(struct hnb_context *ctx); diff --git a/src/osmo-hnbgw/Makefile.am b/src/osmo-hnbgw/Makefile.am index d1179e4..de96128 100644 --- a/src/osmo-hnbgw/Makefile.am +++ b/src/osmo-hnbgw/Makefile.am @@ -43,6 +43,7 @@ ranap_rab_ass.c \ mgw_fsm.c \ tdefs.c \ + osmo_hnbgw_main.c \ $(NULL) osmo_hnbgw_LDADD = \ diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index bad7064..8876580 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -1,7 +1,7 @@ -/* main application for hnb-gw part of osmo-iuh */ +/* kitchen sink for OsmoHNBGW implementation */ /* (C) 2015 by Harald Welte <lafo...@gnumonks.org> - * (C) 2016 by sysmocom s.f.m.c. GmbH <i...@sysmocom.de> + * (C) 2016-2023 by sysmocom s.f.m.c. GmbH <i...@sysmocom.de> * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -19,49 +19,14 @@ * */ -#include "config.h" - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <errno.h> -#include <signal.h> -#include <stdbool.h> - -#include <sys/types.h> -#include <sys/socket.h> #include <netinet/in.h> #include <netinet/sctp.h> -#include <arpa/inet.h> -#include <osmocom/core/application.h> -#include <osmocom/core/talloc.h> -#include <osmocom/core/select.h> -#include <osmocom/core/logging.h> -#include <osmocom/core/socket.h> -#include <osmocom/core/msgb.h> -#include <osmocom/core/write_queue.h> -#include <osmocom/ctrl/control_if.h> -#include <osmocom/ctrl/control_cmd.h> -#include <osmocom/ctrl/control_vty.h> -#include <osmocom/ctrl/ports.h> -#include <osmocom/vty/telnet_interface.h> -#include <osmocom/vty/logging.h> -#include <osmocom/vty/misc.h> -#include <osmocom/vty/command.h> -#include <osmocom/vty/ports.h> - -#include <osmocom/mgcp_client/mgcp_client.h> +#include <osmocom/vty/vty.h> #include <osmocom/netif/stream.h> -#include <osmocom/ranap/ranap_common.h> - -#include <osmocom/sigtran/protocol/m3ua.h> -#include <osmocom/sigtran/sccp_sap.h> - +#include "config.h" #if ENABLE_PFCP #include <osmocom/pfcp/pfcp_proto.h> #endif @@ -69,21 +34,11 @@ #include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/hnbgw_hnbap.h> #include <osmocom/hnbgw/hnbgw_rua.h> -#include <osmocom/hnbgw/hnbgw_cn.h> -#include <osmocom/hnbgw/hnbgw_pfcp.h> #include <osmocom/hnbgw/context_map.h> -static const char * const osmo_hnbgw_copyright = - "OsmoHNBGW - Osmocom Home Node B Gateway implementation\r\n" - "Copyright (C) 2016 by sysmocom s.f.m.c. GmbH <i...@sysmocom.de>\r\n" - "Contributions by Daniel Willmann, Harald Welte, Neels Hofmeyr\r\n" - "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n" - "This is free software: you are free to change and redistribute it.\r\n" - "There is NO WARRANTY, to the extent permitted by law.\r\n"; - struct hnbgw *g_hnbgw = NULL; -static void g_hnbgw_alloc(void *ctx) +void g_hnbgw_alloc(void *ctx) { OSMO_ASSERT(!g_hnbgw); g_hnbgw = talloc_zero(ctx, struct hnbgw); @@ -106,7 +61,7 @@ #endif } -struct hnb_context *hnb_context_by_id(uint32_t cid) +static struct hnb_context *hnb_context_by_id(uint32_t cid) { struct hnb_context *hnb; @@ -164,7 +119,7 @@ return NULL; } -void ue_context_free_by_hnb(const struct hnb_context *hnb) +static void ue_context_free_by_hnb(const struct hnb_context *hnb) { struct ue_context *ue, *tmp; @@ -334,7 +289,7 @@ return 0; } -struct hnb_context *hnb_context_alloc(struct osmo_stream_srv_link *link, int new_fd) +static struct hnb_context *hnb_context_alloc(struct osmo_stream_srv_link *link, int new_fd) { struct hnb_context *ctx; @@ -416,7 +371,7 @@ } /*! call-back when the listen FD has something to read */ -static int accept_cb(struct osmo_stream_srv_link *srv, int fd) +int hnbgw_rua_accept_cb(struct osmo_stream_srv_link *srv, int fd) { struct hnb_context *ctx; @@ -430,185 +385,6 @@ return 0; } -static const struct log_info_cat log_cat[] = { - [DMAIN] = { - .name = "DMAIN", .loglevel = LOGL_NOTICE, .enabled = 1, - .color = "", - .description = "Main program", - }, - [DHNBAP] = { - .name = "DHNBAP", .loglevel = LOGL_NOTICE, .enabled = 1, - .color = "", - .description = "Home Node B Application Part", - }, - [DRUA] = { - .name = "DRUA", .loglevel = LOGL_NOTICE, .enabled = 1, - .color = "", - .description = "RANAP User Adaptation", - }, - [DRANAP] = { - .name = "DRANAP", .loglevel = LOGL_NOTICE, .enabled = 1, - .color = "", - .description = "RAN Application Part", - }, - [DMGW] = { - .name = "DMGW", .loglevel = LOGL_NOTICE, .enabled = 1, - .color = "\033[1;33m", - .description = "Media Gateway", - }, - [DHNB] = { - .name = "DHNB", .loglevel = LOGL_NOTICE, .enabled = 1, - .color = OSMO_LOGCOLOR_CYAN, - .description = "HNB side (via RUA)", - }, - [DCN] = { - .name = "DCN", .loglevel = LOGL_NOTICE, .enabled = 1, - .color = OSMO_LOGCOLOR_DARKYELLOW, - .description = "Core Network side (via SCCP)", - }, -}; - -static const struct log_info hnbgw_log_info = { - .cat = log_cat, - .num_cat = ARRAY_SIZE(log_cat), -}; - -static struct vty_app_info vty_info = { - .name = "OsmoHNBGW", - .version = PACKAGE_VERSION, - .go_parent_cb = hnbgw_vty_go_parent, -}; - -static struct { - int daemonize; - const char *config_file; - bool log_disable_color; - bool log_enable_timestamp; - int log_level; - const char *log_category_mask; -} hnbgw_cmdline_config = { - 0, - "osmo-hnbgw.cfg", - false, - false, - 0, - NULL, -}; - -static void print_usage() -{ - printf("Usage: osmo-hnbgw\n"); -} - -static void print_help() -{ - printf(" -h --help This text.\n"); - printf(" -d option --debug=DHNBAP:DRUA:DRANAP:DMAIN Enable debugging.\n"); - printf(" -D --daemonize Fork the process into a background daemon.\n"); - printf(" -c --config-file filename The config file to use.\n"); - printf(" -s --disable-color\n"); - printf(" -T --timestamp Prefix every log line with a timestamp.\n"); - printf(" -V --version Print the version of OsmoHNBGW.\n"); - printf(" -e --log-level number Set a global loglevel.\n"); - - printf("\nVTY reference generation:\n"); - printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n"); - printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n"); -} - -static void handle_long_options(const char *prog_name, const int long_option) -{ - static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT; - - switch (long_option) { - case 1: - vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg); - if (vty_ref_mode < 0) { - fprintf(stderr, "%s: Unknown VTY reference generation " - "mode '%s'\n", prog_name, optarg); - exit(2); - } - break; - case 2: - fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n", - get_value_string(vty_ref_gen_mode_names, vty_ref_mode), - get_value_string(vty_ref_gen_mode_desc, vty_ref_mode)); - vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode); - exit(0); - default: - fprintf(stderr, "%s: error parsing cmdline options\n", prog_name); - exit(2); - } -} - -static void handle_options(int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static int long_option = 0; - static struct option long_options[] = { - {"help", 0, 0, 'h'}, - {"debug", 1, 0, 'd'}, - {"daemonize", 0, 0, 'D'}, - {"config-file", 1, 0, 'c'}, - {"disable-color", 0, 0, 's'}, - {"timestamp", 0, 0, 'T'}, - {"version", 0, 0, 'V' }, - {"log-level", 1, 0, 'e'}, - {"vty-ref-mode", 1, &long_option, 1}, - {"vty-ref-xml", 0, &long_option, 2}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "hd:Dc:sTVe:", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 0: - handle_long_options(argv[0], long_option); - break; - case 'h': - print_usage(); - print_help(); - exit(0); - case 's': - hnbgw_cmdline_config.log_disable_color = true; - break; - case 'd': - hnbgw_cmdline_config.log_category_mask = optarg; - break; - case 'D': - hnbgw_cmdline_config.daemonize = 1; - break; - case 'c': - hnbgw_cmdline_config.config_file = optarg; - break; - case 'T': - hnbgw_cmdline_config.log_enable_timestamp = true; - break; - case 'e': - hnbgw_cmdline_config.log_level = atoi(optarg); - break; - case 'V': - print_version(1); - exit(0); - break; - default: - /* catch unknown options *as well as* missing arguments. */ - fprintf(stderr, "Error in command line options. Exiting.\n"); - exit(-1); - break; - } - } - - if (argc > optind) { - fprintf(stderr, "Unsupported positional arguments on command line\n"); - exit(2); - } -} - CTRL_CMD_DEFINE_RO(hnb_info, "info"); static int get_hnb_info(struct ctrl_cmd *cmd, void *data) { @@ -627,7 +403,7 @@ return CTRL_CMD_REPLY; } -int hnb_ctrl_cmds_install() +int hnb_ctrl_cmds_install(void) { int rc = 0; @@ -637,7 +413,7 @@ return rc; } -static int hnb_ctrl_node_lookup(void *data, vector vline, int *node_type, void **node_data, int *i) +int hnb_ctrl_node_lookup(void *data, vector vline, int *node_type, void **node_data, int *i) { const char *token = vector_slot(vline, *i); struct hnb_context *hnb; @@ -667,7 +443,7 @@ return 1; } -static int hnbgw_mgw_setup(void) +int hnbgw_mgw_setup(void) { struct mgcp_client *mgcp_client_single; unsigned int pool_members_initalized; @@ -706,147 +482,6 @@ return 0; } -int main(int argc, char **argv) -{ - struct osmo_stream_srv_link *srv; - int rc; - - talloc_enable_null_tracking(); - - /* g_hnbgw serves as the root talloc ctx, so allocate with NULL parent */ - g_hnbgw_alloc(NULL); - g_hnbgw->config.rnc_id = 23; - - talloc_asn1_ctx = talloc_named_const(g_hnbgw, 1, "asn1_context"); - msgb_talloc_ctx_init(g_hnbgw, 0); - - rc = osmo_init_logging2(g_hnbgw, &hnbgw_log_info); - if (rc < 0) - exit(1); - - osmo_fsm_log_timeouts(true); - - rc = osmo_ss7_init(); - if (rc < 0) { - LOGP(DMAIN, LOGL_FATAL, "osmo_ss7_init() failed with rc=%d\n", rc); - exit(1); - } - - vty_info.tall_ctx = g_hnbgw; - vty_info.copyright = osmo_hnbgw_copyright; - vty_init(&vty_info); - - osmo_ss7_vty_init_asp(g_hnbgw); - osmo_sccp_vty_init(); - hnbgw_vty_init(); - ctrl_vty_init(g_hnbgw); - logging_vty_add_cmds(); - osmo_talloc_vty_add_cmds(); - - /* Handle options after vty_init(), for --version */ - handle_options(argc, argv); - - rc = vty_read_config_file(hnbgw_cmdline_config.config_file, NULL); - if (rc < 0) { - LOGP(DMAIN, LOGL_FATAL, "Failed to parse the config file: '%s'\n", - hnbgw_cmdline_config.config_file); - return 1; - } - - /* - * cmdline options take precedence over config file, but if no options - * were passed we must not override the config file. - */ - if (hnbgw_cmdline_config.log_disable_color) - log_set_use_color(osmo_stderr_target, 0); - if (hnbgw_cmdline_config.log_category_mask) - log_parse_category_mask(osmo_stderr_target, - hnbgw_cmdline_config.log_category_mask); - if (hnbgw_cmdline_config.log_enable_timestamp) - log_set_print_timestamp(osmo_stderr_target, 1); - if (hnbgw_cmdline_config.log_level) - log_set_log_level(osmo_stderr_target, - hnbgw_cmdline_config.log_level); - - rc = telnet_init_default(g_hnbgw, g_hnbgw, OSMO_VTY_PORT_HNBGW); - if (rc < 0) { - perror("Error binding VTY port"); - exit(1); - } - - g_hnbgw->ctrl = ctrl_interface_setup2(g_hnbgw, OSMO_CTRL_PORT_HNBGW, hnb_ctrl_node_lookup, - _LAST_CTRL_NODE_HNB); - if (!g_hnbgw->ctrl) { - LOGP(DMAIN, LOGL_ERROR, "Failed to create CTRL interface on %s:%u\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_HNBGW); - exit(1); - } else { - rc = hnb_ctrl_cmds_install(); - if (rc) { - LOGP(DMAIN, LOGL_ERROR, "Failed to install CTRL interface commands\n"); - return 2; - } - } - - ranap_set_log_area(DRANAP); - - rc = hnbgw_cnlink_init("localhost", M3UA_PORT, "localhost"); - if (rc < 0) { - LOGP(DMAIN, LOGL_ERROR, "Failed to initialize SCCP link to CN\n"); - exit(1); - } - - LOGP(DHNBAP, LOGL_NOTICE, "Using RNC-Id %u\n", g_hnbgw->config.rnc_id); - - OSMO_ASSERT(g_hnbgw->config.iuh_local_ip); - LOGP(DMAIN, LOGL_NOTICE, "Listening for Iuh at %s %d\n", - g_hnbgw->config.iuh_local_ip, - g_hnbgw->config.iuh_local_port); - srv = osmo_stream_srv_link_create(g_hnbgw); - if (!srv) { - perror("cannot create server"); - exit(1); - } - osmo_stream_srv_link_set_data(srv, g_hnbgw); - osmo_stream_srv_link_set_proto(srv, IPPROTO_SCTP); - osmo_stream_srv_link_set_nodelay(srv, true); - osmo_stream_srv_link_set_addr(srv, g_hnbgw->config.iuh_local_ip); - osmo_stream_srv_link_set_port(srv, g_hnbgw->config.iuh_local_port); - osmo_stream_srv_link_set_accept_cb(srv, accept_cb); - - if (osmo_stream_srv_link_open(srv) < 0) { - perror("Cannot open server"); - exit(1); - } - g_hnbgw->iuh = srv; - - /* Initialize and connect MGCP client. */ - if (hnbgw_mgw_setup() != 0) - return -EINVAL; - -#if ENABLE_PFCP - /* If UPF is configured, set up PFCP socket and send Association Setup Request to UPF */ - hnbgw_pfcp_init(); -#endif - - if (hnbgw_cmdline_config.daemonize) { - rc = osmo_daemonize(); - if (rc < 0) { - perror("Error during daemonize"); - exit(1); - } - } - - while (1) { - rc = osmo_select_main_ctx(0); - if (rc < 0) - exit(3); - } - - /* not reached */ - exit(0); -} - struct msgb *hnbgw_ranap_msg_alloc(const char *name) { struct msgb *ranap_msg; @@ -855,3 +490,61 @@ ranap_msg->l2h = ranap_msg->data; return ranap_msg; } + +static const char * const hnbgw_copyright = + "OsmoHNBGW - Osmocom Home Node B Gateway implementation\r\n" + "Copyright (C) 2016-2023 by sysmocom s.f.m.c. GmbH <i...@sysmocom.de>\r\n" + "Contributions by Daniel Willmann, Harald Welte, Neels Hofmeyr\r\n" + "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n" + "This is free software: you are free to change and redistribute it.\r\n" + "There is NO WARRANTY, to the extent permitted by law.\r\n"; + +static const struct log_info_cat hnbgw_log_cat[] = { + [DMAIN] = { + .name = "DMAIN", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = "", + .description = "Main program", + }, + [DHNBAP] = { + .name = "DHNBAP", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = "", + .description = "Home Node B Application Part", + }, + [DRUA] = { + .name = "DRUA", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = "", + .description = "RANAP User Adaptation", + }, + [DRANAP] = { + .name = "DRANAP", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = "", + .description = "RAN Application Part", + }, + [DMGW] = { + .name = "DMGW", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = "\033[1;33m", + .description = "Media Gateway", + }, + [DHNB] = { + .name = "DHNB", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = OSMO_LOGCOLOR_CYAN, + .description = "HNB side (via RUA)", + }, + [DCN] = { + .name = "DCN", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = OSMO_LOGCOLOR_DARKYELLOW, + .description = "Core Network side (via SCCP)", + }, +}; + +const struct log_info hnbgw_log_info = { + .cat = hnbgw_log_cat, + .num_cat = ARRAY_SIZE(hnbgw_log_cat), +}; + +struct vty_app_info hnbgw_vty_info = { + .name = "OsmoHNBGW", + .version = PACKAGE_VERSION, + .go_parent_cb = hnbgw_vty_go_parent, + .copyright = hnbgw_copyright, +}; diff --git a/src/osmo-hnbgw/osmo_hnbgw_main.c b/src/osmo-hnbgw/osmo_hnbgw_main.c new file mode 100644 index 0000000..abb577c --- /dev/null +++ b/src/osmo-hnbgw/osmo_hnbgw_main.c @@ -0,0 +1,317 @@ +/* OsmoHNBGW main routine */ + +/* (C) 2015 by Harald Welte <lafo...@gnumonks.org> + * (C) 2016-2023 by sysmocom s.f.m.c. GmbH <i...@sysmocom.de> + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <getopt.h> + +#include "config.h" + +#include <osmocom/core/application.h> +#include <osmocom/core/logging.h> + +#include <osmocom/vty/vty.h> +#include <osmocom/vty/command.h> +#include <osmocom/vty/logging.h> +#include <osmocom/vty/misc.h> +#include <osmocom/vty/telnet_interface.h> +#include <osmocom/vty/ports.h> + +#include <osmocom/ctrl/control_vty.h> +#include <osmocom/ctrl/ports.h> + +#include <osmocom/netif/stream.h> + +#include <osmocom/sigtran/protocol/m3ua.h> + +#include <osmocom/ranap/ranap_common.h> + +#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/hnbgw_cn.h> +#include <osmocom/hnbgw/hnbgw_pfcp.h> + +static struct { + int daemonize; + const char *config_file; + bool log_disable_color; + bool log_enable_timestamp; + int log_level; + const char *log_category_mask; +} hnbgw_cmdline_config = { + 0, + "osmo-hnbgw.cfg", + false, + false, + 0, + NULL, +}; + +static void print_usage() +{ + printf("Usage: osmo-hnbgw\n"); +} + +static void print_help() +{ + printf(" -h --help This text.\n"); + printf(" -d option --debug=DHNBAP:DRUA:DRANAP:DMAIN Enable debugging.\n"); + printf(" -D --daemonize Fork the process into a background daemon.\n"); + printf(" -c --config-file filename The config file to use.\n"); + printf(" -s --disable-color\n"); + printf(" -T --timestamp Prefix every log line with a timestamp.\n"); + printf(" -V --version Print the version of OsmoHNBGW.\n"); + printf(" -e --log-level number Set a global loglevel.\n"); + + printf("\nVTY reference generation:\n"); + printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n"); + printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n"); +} + +static void handle_long_options(const char *prog_name, const int long_option) +{ + static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT; + + switch (long_option) { + case 1: + vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg); + if (vty_ref_mode < 0) { + fprintf(stderr, "%s: Unknown VTY reference generation " + "mode '%s'\n", prog_name, optarg); + exit(2); + } + break; + case 2: + fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n", + get_value_string(vty_ref_gen_mode_names, vty_ref_mode), + get_value_string(vty_ref_gen_mode_desc, vty_ref_mode)); + vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode); + exit(0); + default: + fprintf(stderr, "%s: error parsing cmdline options\n", prog_name); + exit(2); + } +} + +static void handle_options(int argc, char **argv) +{ + while (1) { + int option_index = 0, c; + static int long_option = 0; + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"debug", 1, 0, 'd'}, + {"daemonize", 0, 0, 'D'}, + {"config-file", 1, 0, 'c'}, + {"disable-color", 0, 0, 's'}, + {"timestamp", 0, 0, 'T'}, + {"version", 0, 0, 'V' }, + {"log-level", 1, 0, 'e'}, + {"vty-ref-mode", 1, &long_option, 1}, + {"vty-ref-xml", 0, &long_option, 2}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "hd:Dc:sTVe:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 0: + handle_long_options(argv[0], long_option); + break; + case 'h': + print_usage(); + print_help(); + exit(0); + case 's': + hnbgw_cmdline_config.log_disable_color = true; + break; + case 'd': + hnbgw_cmdline_config.log_category_mask = optarg; + break; + case 'D': + hnbgw_cmdline_config.daemonize = 1; + break; + case 'c': + hnbgw_cmdline_config.config_file = optarg; + break; + case 'T': + hnbgw_cmdline_config.log_enable_timestamp = true; + break; + case 'e': + hnbgw_cmdline_config.log_level = atoi(optarg); + break; + case 'V': + print_version(1); + exit(0); + break; + default: + /* catch unknown options *as well as* missing arguments. */ + fprintf(stderr, "Error in command line options. Exiting.\n"); + exit(-1); + break; + } + } + + if (argc > optind) { + fprintf(stderr, "Unsupported positional arguments on command line\n"); + exit(2); + } +} + +int main(int argc, char **argv) +{ + struct osmo_stream_srv_link *srv; + int rc; + + talloc_enable_null_tracking(); + + /* g_hnbgw serves as the root talloc ctx, so allocate with NULL parent */ + g_hnbgw_alloc(NULL); + g_hnbgw->config.rnc_id = 23; + + talloc_asn1_ctx = talloc_named_const(g_hnbgw, 1, "asn1_context"); + msgb_talloc_ctx_init(g_hnbgw, 0); + + rc = osmo_init_logging2(g_hnbgw, &hnbgw_log_info); + if (rc < 0) + exit(1); + + osmo_fsm_log_timeouts(true); + + rc = osmo_ss7_init(); + if (rc < 0) { + LOGP(DMAIN, LOGL_FATAL, "osmo_ss7_init() failed with rc=%d\n", rc); + exit(1); + } + + hnbgw_vty_info.tall_ctx = g_hnbgw; + vty_init(&hnbgw_vty_info); + + osmo_ss7_vty_init_asp(g_hnbgw); + osmo_sccp_vty_init(); + hnbgw_vty_init(); + ctrl_vty_init(g_hnbgw); + logging_vty_add_cmds(); + osmo_talloc_vty_add_cmds(); + + /* Handle options after vty_init(), for --version */ + handle_options(argc, argv); + + rc = vty_read_config_file(hnbgw_cmdline_config.config_file, NULL); + if (rc < 0) { + LOGP(DMAIN, LOGL_FATAL, "Failed to parse the config file: '%s'\n", + hnbgw_cmdline_config.config_file); + return 1; + } + + /* + * cmdline options take precedence over config file, but if no options + * were passed we must not override the config file. + */ + if (hnbgw_cmdline_config.log_disable_color) + log_set_use_color(osmo_stderr_target, 0); + if (hnbgw_cmdline_config.log_category_mask) + log_parse_category_mask(osmo_stderr_target, + hnbgw_cmdline_config.log_category_mask); + if (hnbgw_cmdline_config.log_enable_timestamp) + log_set_print_timestamp(osmo_stderr_target, 1); + if (hnbgw_cmdline_config.log_level) + log_set_log_level(osmo_stderr_target, + hnbgw_cmdline_config.log_level); + + rc = telnet_init_default(g_hnbgw, g_hnbgw, OSMO_VTY_PORT_HNBGW); + if (rc < 0) { + perror("Error binding VTY port"); + exit(1); + } + + g_hnbgw->ctrl = ctrl_interface_setup2(g_hnbgw, OSMO_CTRL_PORT_HNBGW, hnb_ctrl_node_lookup, + _LAST_CTRL_NODE_HNB); + if (!g_hnbgw->ctrl) { + LOGP(DMAIN, LOGL_ERROR, "Failed to create CTRL interface on %s:%u\n", + ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_HNBGW); + exit(1); + } else { + rc = hnb_ctrl_cmds_install(); + if (rc) { + LOGP(DMAIN, LOGL_ERROR, "Failed to install CTRL interface commands\n"); + return 2; + } + } + + ranap_set_log_area(DRANAP); + + rc = hnbgw_cnlink_init("localhost", M3UA_PORT, "localhost"); + if (rc < 0) { + LOGP(DMAIN, LOGL_ERROR, "Failed to initialize SCCP link to CN\n"); + exit(1); + } + + LOGP(DHNBAP, LOGL_NOTICE, "Using RNC-Id %u\n", g_hnbgw->config.rnc_id); + + OSMO_ASSERT(g_hnbgw->config.iuh_local_ip); + LOGP(DMAIN, LOGL_NOTICE, "Listening for Iuh at %s %d\n", + g_hnbgw->config.iuh_local_ip, + g_hnbgw->config.iuh_local_port); + srv = osmo_stream_srv_link_create(g_hnbgw); + if (!srv) { + perror("cannot create server"); + exit(1); + } + osmo_stream_srv_link_set_data(srv, g_hnbgw); + osmo_stream_srv_link_set_proto(srv, IPPROTO_SCTP); + osmo_stream_srv_link_set_nodelay(srv, true); + osmo_stream_srv_link_set_addr(srv, g_hnbgw->config.iuh_local_ip); + osmo_stream_srv_link_set_port(srv, g_hnbgw->config.iuh_local_port); + osmo_stream_srv_link_set_accept_cb(srv, hnbgw_rua_accept_cb); + + if (osmo_stream_srv_link_open(srv) < 0) { + perror("Cannot open server"); + exit(1); + } + g_hnbgw->iuh = srv; + + /* Initialize and connect MGCP client. */ + if (hnbgw_mgw_setup() != 0) + return -EINVAL; + +#if ENABLE_PFCP + /* If UPF is configured, set up PFCP socket and send Association Setup Request to UPF */ + hnbgw_pfcp_init(); +#endif + + if (hnbgw_cmdline_config.daemonize) { + rc = osmo_daemonize(); + if (rc < 0) { + perror("Error during daemonize"); + exit(1); + } + } + + while (1) { + rc = osmo_select_main_ctx(0); + if (rc < 0) + exit(3); + } + + /* not reached */ + exit(0); +} -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32620 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I5f26a6b68f0d380617d73371f40f3b9055cac362 Gerrit-Change-Number: 32620 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofm...@sysmocom.de> Gerrit-MessageType: newchange