misc: Fix crash in cell_log due missing l1_prim_cb
[osmocom-bb.git] / src / host / layer23 / src / common / main.c
index ba16a32..666e94a 100644 (file)
 #include <osmocom/bb/common/logging.h>
 #include <osmocom/bb/common/l23_app.h>
 
-#include <osmocore/msgb.h>
-#include <osmocore/talloc.h>
-#include <osmocore/select.h>
-#include <osmocore/linuxlist.h>
-#include <osmocore/gsmtap_util.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/gsmtap_util.h>
+#include <osmocom/core/gsmtap.h>
+#include <osmocom/core/utils.h>
 
 #include <arpa/inet.h>
 
 struct log_target *stderr_target;
 
 void *l23_ctx = NULL;
+
 static char *layer2_socket_path = "/tmp/osmocom_l2";
 static char *sap_socket_path = "/tmp/osmocom_sap";
 struct llist_head ms_list;
 static struct osmocom_ms *ms = NULL;
-static uint32_t gsmtap_ip = 0;
+static char *gsmtap_ip = NULL;
+
 unsigned short vty_port = 4247;
 int (*l23_app_work) (struct osmocom_ms *ms) = NULL;
 int (*l23_app_exit) (struct osmocom_ms *ms) = NULL;
 int quit = 0;
+struct gsmtap_inst *gsmtap_inst;
 
 const char *openbsc_copyright =
-       "Copyright (C) 2008-2010 ...\n"
-       "Contributions by ...\n\n"
+       "%s"
+       "%s\n"
        "License GPLv2+: GNU GPL version 2 or later "
                "<http://gnu.org/licenses/gpl.html>\n"
        "This is free software: you are free to change and redistribute it.\n"
-       "There is NO WARRANTY, to the extent permitted by law.\n";
+       "There is NO WARRANTY, to the extent permitted by law.\n\n";
 
 static void print_usage(const char *app)
 {
@@ -74,36 +79,80 @@ static void print_usage(const char *app)
 
 static void print_help()
 {
+       int options = 0xff;
+       struct l23_app_info *app = l23_app_info();
+
+       if (app && app->cfg_supported != 0)
+               options = app->cfg_supported();
+
        printf(" Some help...\n");
        printf("  -h --help             this text\n");
        printf("  -s --socket           /tmp/osmocom_l2. Path to the unix "
                "domain socket (l2)\n");
-       printf("  -S --sap              /tmp/osmocom_sap. Path to the unix "
-               "domain socket (BTSAP)\n");
-       printf("  -a --arfcn NR         The ARFCN to be used for layer2.\n");
-       printf("  -i --gsmtap-ip        The destination IP used for GSMTAP.\n");
-       printf("  -v --vty-port         The VTY port number to telnet to. "
-               "(default %u)\n", vty_port);
-       printf("  -d --debug            Change debug flags.\n");
+
+       if (options & L23_OPT_SAP)
+               printf("  -S --sap              /tmp/osmocom_sap. Path to the "
+                       "unix domain socket (BTSAP)\n");
+
+       if (options & L23_OPT_ARFCN)
+               printf("  -a --arfcn NR         The ARFCN to be used for layer2.\n");
+
+       if (options & L23_OPT_TAP)
+               printf("  -i --gsmtap-ip        The destination IP used for GSMTAP.\n");
+
+       if (options & L23_OPT_VTY)
+               printf("  -v --vty-port         The VTY port number to telnet "
+                       "to. (default %u)\n", vty_port);
+
+       if (options & L23_OPT_DBG)
+               printf("  -d --debug            Change debug flags.\n");
+
+       if (app && app->cfg_print_help)
+               app->cfg_print_help();
+}
+
+static void build_config(char **opt, struct option **option)
+{
+       struct l23_app_info *app;
+       struct option *app_opp = NULL;
+       int app_len = 0, len;
+
+       static struct option long_options[] = {
+               {"help", 0, 0, 'h'},
+               {"socket", 1, 0, 's'},
+               {"sap", 1, 0, 'S'},
+               {"arfcn", 1, 0, 'a'},
+               {"gsmtap-ip", 1, 0, 'i'},
+               {"vty-port", 1, 0, 'v'},
+               {"debug", 1, 0, 'd'},
+       };
+
+
+       app = l23_app_info();
+       *opt = talloc_asprintf(l23_ctx, "hs:S:a:i:v:d:%s",
+                              app && app->getopt_string ? app->getopt_string : "");
+
+       len = ARRAY_SIZE(long_options);
+       if (app && app->cfg_getopt_opt)
+               app_len = app->cfg_getopt_opt(&app_opp);
+
+       *option = talloc_zero_array(l23_ctx, struct option, len + app_len + 1);
+       memcpy(*option, long_options, sizeof(long_options));
+       memcpy(*option + len, app_opp, app_len * sizeof(struct option));
 }
 
 static void handle_options(int argc, char **argv)
 {
-       struct sockaddr_in gsmtap;
+       struct l23_app_info *app = l23_app_info();
+       struct option *long_options;
+       char *opt;
+
+       build_config(&opt, &long_options);
+
        while (1) {
                int option_index = 0, c;
-               static struct option long_options[] = {
-                       {"help", 0, 0, 'h'},
-                       {"socket", 1, 0, 's'},
-                       {"sap", 1, 0, 'S'},
-                       {"arfcn", 1, 0, 'a'},
-                       {"gsmtap-ip", 1, 0, 'i'},
-                       {"vty-port", 1, 0, 'v'},
-                       {"debug", 1, 0, 'd'},
-                       {0, 0, 0, 0},
-               };
-
-               c = getopt_long(argc, argv, "hs:S:a:i:v:d:",
+
+               c = getopt_long(argc, argv, opt,
                                long_options, &option_index);
                if (c == -1)
                        break;
@@ -124,11 +173,7 @@ static void handle_options(int argc, char **argv)
                        ms->test_arfcn = atoi(optarg);
                        break;
                case 'i':
-                       if (!inet_aton(optarg, &gsmtap.sin_addr)) {
-                               perror("inet_aton");
-                               exit(2);
-                       }
-                       gsmtap_ip = ntohl(gsmtap.sin_addr.s_addr);
+                       gsmtap_ip = optarg;
                        break;
                case 'v':
                        vty_port = atoi(optarg);
@@ -137,9 +182,14 @@ static void handle_options(int argc, char **argv)
                        log_parse_category_mask(stderr_target, optarg);
                        break;
                default:
+                       if (app && app->cfg_handle_opt)
+                               app->cfg_handle_opt(c, optarg);
                        break;
                }
        }
+
+       talloc_free(opt);
+       talloc_free(long_options);
 }
 
 void sighandler(int sigset)
@@ -157,12 +207,19 @@ void sighandler(int sigset)
                exit (0);
 }
 
+static void print_copyright()
+{
+       struct l23_app_info *app;
+       app = l23_app_info();
+       printf(openbsc_copyright,
+              app && app->copyright ? app->copyright : "",
+              app && app->contribution ? app->contribution : "");
+}
+
 int main(int argc, char **argv)
 {
        int rc;
 
-       printf("%s\n", openbsc_copyright);
-
        INIT_LLIST_HEAD(&ms_list);
        log_init(&log_info);
        stderr_target = log_target_create_stderr();
@@ -176,6 +233,9 @@ int main(int argc, char **argv)
                fprintf(stderr, "Failed to allocate MS\n");
                exit(1);
        }
+
+       print_copyright();
+
        llist_add_tail(&ms->entity, &ms_list);
 
        sprintf(ms->name, "1");
@@ -194,19 +254,24 @@ int main(int argc, char **argv)
        if (rc < 0)
                fprintf(stderr, "Failed during sap_open(), no SIM reader\n");
 
-       lapdm_init(&ms->l2_entity.lapdm_dcch, ms);
-       lapdm_init(&ms->l2_entity.lapdm_acch, ms);
+       ms->lapdm_channel.lapdm_dcch.l1_ctx = ms;
+       ms->lapdm_channel.lapdm_dcch.l3_ctx = ms;
+       ms->lapdm_channel.lapdm_acch.l1_ctx = ms;
+       ms->lapdm_channel.lapdm_acch.l3_ctx = ms;
+       lapdm_channel_init(&ms->lapdm_channel, LAPDM_MODE_MS);
+       lapdm_channel_set_l1(&ms->lapdm_channel, l1ctl_ph_prim_cb, ms);
 
        rc = l23_app_init(ms);
        if (rc < 0)
                exit(1);
 
        if (gsmtap_ip) {
-               rc = gsmtap_init(gsmtap_ip);
-               if (rc < 0) {
+               gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
+               if (!gsmtap_inst) {
                        fprintf(stderr, "Failed during gsmtap_init()\n");
                        exit(1);
                }
+               gsmtap_source_add_sink(gsmtap_inst);
        }
 
        signal(SIGINT, sighandler);
@@ -217,7 +282,7 @@ int main(int argc, char **argv)
        while (!quit) {
                if (l23_app_work)
                        l23_app_work(ms);
-               bsc_select_main(0);
+               osmo_select_main(0);
        }
 
        return 0;